armadeus-commitlog Mailing List for armadeus (Page 139)
Brought to you by:
sszy
You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(43) |
Feb
(8) |
Mar
(7) |
Apr
(8) |
May
(14) |
Jun
(6) |
Jul
(4) |
Aug
(17) |
Sep
(18) |
Oct
(19) |
Nov
(52) |
Dec
(30) |
| 2008 |
Jan
(6) |
Feb
(6) |
Mar
(15) |
Apr
(22) |
May
(13) |
Jun
(11) |
Jul
(41) |
Aug
(10) |
Sep
(14) |
Oct
(21) |
Nov
(4) |
Dec
(66) |
| 2009 |
Jan
(67) |
Feb
(57) |
Mar
(90) |
Apr
(54) |
May
(64) |
Jun
(76) |
Jul
(14) |
Aug
(18) |
Sep
(18) |
Oct
(20) |
Nov
(15) |
Dec
(36) |
| 2010 |
Jan
(28) |
Feb
(25) |
Mar
(32) |
Apr
(23) |
May
(22) |
Jun
(62) |
Jul
(36) |
Aug
(16) |
Sep
(12) |
Oct
(20) |
Nov
(44) |
Dec
(25) |
| 2011 |
Jan
(36) |
Feb
(49) |
Mar
(28) |
Apr
(38) |
May
(26) |
Jun
(52) |
Jul
(33) |
Aug
(32) |
Sep
(19) |
Oct
(26) |
Nov
(13) |
Dec
(32) |
| 2012 |
Jan
(38) |
Feb
(34) |
Mar
(91) |
Apr
(35) |
May
(31) |
Jun
(72) |
Jul
(23) |
Aug
(13) |
Sep
(33) |
Oct
(47) |
Nov
(18) |
Dec
(22) |
| 2013 |
Jan
(31) |
Feb
(22) |
Mar
(26) |
Apr
(11) |
May
(38) |
Jun
(15) |
Jul
(37) |
Aug
(68) |
Sep
(34) |
Oct
(11) |
Nov
(26) |
Dec
(31) |
| 2014 |
Jan
(60) |
Feb
(55) |
Mar
(21) |
Apr
(31) |
May
(17) |
Jun
(35) |
Jul
(24) |
Aug
(17) |
Sep
(11) |
Oct
(23) |
Nov
(10) |
Dec
(23) |
| 2015 |
Jan
(15) |
Feb
(34) |
Mar
(46) |
Apr
(23) |
May
(12) |
Jun
(14) |
Jul
(18) |
Aug
(22) |
Sep
(6) |
Oct
(2) |
Nov
(1) |
Dec
(6) |
| 2016 |
Jan
(5) |
Feb
(7) |
Mar
(10) |
Apr
(10) |
May
(17) |
Jun
(6) |
Jul
(4) |
Aug
(6) |
Sep
(22) |
Oct
(8) |
Nov
(9) |
Dec
(5) |
| 2017 |
Jan
(11) |
Feb
(12) |
Mar
(27) |
Apr
(9) |
May
(1) |
Jun
(5) |
Jul
(11) |
Aug
(10) |
Sep
(6) |
Oct
(10) |
Nov
(4) |
Dec
(6) |
| 2018 |
Jan
(6) |
Feb
(13) |
Mar
(9) |
Apr
(7) |
May
(10) |
Jun
(9) |
Jul
(21) |
Aug
(13) |
Sep
(10) |
Oct
(4) |
Nov
(6) |
Dec
(1) |
| 2019 |
Jan
(6) |
Feb
(2) |
Mar
(5) |
Apr
(6) |
May
(19) |
Jun
(14) |
Jul
(18) |
Aug
(3) |
Sep
(5) |
Oct
(7) |
Nov
(8) |
Dec
(4) |
| 2020 |
Jan
(10) |
Feb
(3) |
Mar
(9) |
Apr
(7) |
May
(2) |
Jun
(18) |
Jul
(3) |
Aug
|
Sep
|
Oct
(7) |
Nov
|
Dec
(1) |
| 2021 |
Jan
(9) |
Feb
(6) |
Mar
(4) |
Apr
(11) |
May
(7) |
Jun
(5) |
Jul
(2) |
Aug
(4) |
Sep
(10) |
Oct
(9) |
Nov
(5) |
Dec
|
| 2022 |
Jan
(2) |
Feb
(12) |
Mar
(3) |
Apr
(5) |
May
(1) |
Jun
(3) |
Jul
(2) |
Aug
(1) |
Sep
(4) |
Oct
(4) |
Nov
(1) |
Dec
(3) |
| 2023 |
Jan
(5) |
Feb
(3) |
Mar
(3) |
Apr
(2) |
May
(1) |
Jun
(3) |
Jul
(3) |
Aug
(2) |
Sep
(1) |
Oct
(1) |
Nov
|
Dec
(4) |
| 2024 |
Jan
(2) |
Feb
(3) |
Mar
(8) |
Apr
(4) |
May
(1) |
Jun
(13) |
Jul
(7) |
Aug
(1) |
Sep
(6) |
Oct
(5) |
Nov
(11) |
Dec
(7) |
| 2025 |
Jan
(3) |
Feb
(1) |
Mar
(6) |
Apr
(4) |
May
(4) |
Jun
(1) |
Jul
(1) |
Aug
(7) |
Sep
(4) |
Oct
(4) |
Nov
(4) |
Dec
(1) |
| 2026 |
Jan
(3) |
Feb
(7) |
Mar
(3) |
Apr
(1) |
May
(6) |
Jun
(3) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <ar...@us...> - 2008-09-11 15:11:35
|
Revision: 881
http://armadeus.svn.sourceforge.net/armadeus/?rev=881&view=rev
Author: artemys
Date: 2008-09-11 15:11:45 +0000 (Thu, 11 Sep 2008)
Log Message:
-----------
[LINUX] remove led.c file from Wb_led driver
Removed Paths:
-------------
trunk/target/linux/modules/fpga/others/Wb_led/led.c
Deleted: trunk/target/linux/modules/fpga/others/Wb_led/led.c
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/led.c 2008-09-11 15:08:41 UTC (rev 880)
+++ trunk/target/linux/modules/fpga/others/Wb_led/led.c 2008-09-11 15:11:45 UTC (rev 881)
@@ -1,219 +0,0 @@
-/*
- ***********************************************************************
- *
- * (c) Copyright 2008 Armadeus project
- * Fabien Marteau <fab...@ar...>
- * Driver for Wb_led fpga IP
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- **********************************************************************
- */
-
-#include "led.h"
-
-/***********************************
- * characters file /dev operations
- * *********************************/
-ssize_t led_read(struct file *fildes, char __user *buff,
- size_t count, loff_t *offp){
- struct led_dev *sdev = fildes->private_data;
- u16 data=0;
- PDEBUG("Read value\n");
- if(*offp != 0 ){ /* offset must be 0 */
- PDEBUG("offset %d\n",(int)*offp);
- return 0;
- }
-
- PDEBUG("count %d\n",count);
- if(count > 2){ /* 16bits max*/
- count = 2;
- }
-
- data = ioread16(sdev->fpga_virtual_base_address + sdev->membase);
- PDEBUG("Read %d at %x\n",data,sdev->membase);
-
- /* return data for user */
- if(copy_to_user(buff,&data,count)){
- printk(KERN_WARNING "read : copy to user data error\n");
- return -EFAULT;
- }
- return count;
-}
-
-ssize_t led_write(struct file *fildes, const char __user *
- buff,size_t count, loff_t *offp){
- struct led_dev *sdev = fildes->private_data;
- u16 data=0;
-
- if(*offp != 0){ /* offset must be 0 */
- PDEBUG("offset %d\n",(int)*offp);
- return 0;
- }
-
- PDEBUG("count %d\n",count);
- if(count > 2){ /* 16 bits max)*/
- count = 2;
- }
-
- if(copy_from_user(&data,buff,count)){
- printk(KERN_WARNING "write : copy from user error\n");
- return -EFAULT;
- }
-
- PDEBUG("Write %d at %x\n",data,sdev->membase);
- iowrite16(data,sdev->fpga_virtual_base_address + sdev->membase);
-
- return count;
-}
-
-
-int led_open(struct inode *inode, struct file *filp){
- /* Allocate and fill any data structure to be put in filp->private_data */
- filp->private_data = container_of(inode->i_cdev,struct led_dev, cdev);
- PDEBUG( "Led opened\n");
- return 0;
-}
-
-/* ******************************
- * Init and release functions
- * ******************************/
-int led_release(struct inode *inode, struct file *filp){
- struct led_dev *dev;
- dev = container_of(inode->i_cdev,struct led_dev,cdev);
- PDEBUG( "%s: released\n",dev->name);
- filp->private_data=NULL;
- return 0;
-}
-
-int register_led(struct plat_led_port *dev){
- int result = 0; /* error return */
- int led_major,led_minor;
- u16 data;
- struct led_dev *sdev = &led_device[dev->num];
- PDEBUG("Register %d led\n",dev->num);
- /* major and minor number */
- led_major = 253;
- led_minor = dev->num ;
-
- sdev->fpga_virtual_base_address = (void*)IMX_CS1_VIRT;
- sdev->membase = dev->membase;
-
- /* name and address of the instance */
- sdev->name = (char *)kmalloc((1+strlen(dev->name))*sizeof(char),GFP_KERNEL);
- if(sdev->name == NULL){
- printk("Kmalloc name space error\n");
- goto error;
- }
- if(strncpy(sdev->name,dev->name,1+strlen(dev->name)) < 0){
- printk("copy error");
- goto error;
- }
-
- /* Get the major and minor device numbers */
- PDEBUG("%s:Get the major and minor device numbers\n",dev->name);
- if(led_major){
- sdev->devno = MKDEV(led_major,led_minor);
- result = register_chrdev_region(sdev->devno, 1,dev->name);
- }else{
- result = alloc_chrdev_region(&sdev->devno,led_minor,1,dev->name);
- led_major = MAJOR(sdev->devno);
- }
-
- printk(KERN_INFO "%s: MAJOR: %d MINOR: %d\n",dev->name,MAJOR(sdev->devno),MINOR(sdev->devno));
- if(result < 0){
- printk(KERN_WARNING "%s: can't get major %d\n",dev->name,led_major);
- goto error;
- }
-
- /* Init the cdev structure */
- PDEBUG("%s:Init the cdev structure\n",dev->name);
- cdev_init(&sdev->cdev,&led_fops);
- sdev->cdev.owner = THIS_MODULE;
- sdev->cdev.ops = &led_fops;
-
- /* Add the device to the kernel, connecting cdev to major/minor number */
- PDEBUG("%s:Add the device to the kernel, connecting cdev to major/minor number \n",dev->name);
- result = cdev_add(&sdev->cdev,sdev->devno,1);
- if(result){
- printk(KERN_WARNING "%s: can't add cdev\n",dev->name);
- goto error;
- }
-
- /* initialize led value */
- data=1;
- iowrite16(data,sdev->fpga_virtual_base_address + sdev->membase);
- PDEBUG("Wrote %x at %x\n",data,sdev->membase);
-
- /* OK module inserted ! */
- printk(KERN_INFO "Led module %s insered\n",dev->name);
- return 0;
-
-error:
- printk(KERN_ERR "%s: not inserted\n",dev->name);
- free_all(dev);
- return result;
-}
-
-/**********************************
- * driver probe
- **********************************/
-static int led_probe(struct platform_device *dev){
-
- /* new code for led with platform device */
- struct plat_led_port *p = dev->dev.platform_data;
- int ret,i;
-
- PDEBUG("Led probing\n");
- /* register each led in plat_led_port tab */
- for (i = 0; p->name!=NULL ; p++, i++) {
- PDEBUG("%s:register led number %d\n",p->name,i);
- ret = register_led(p);
- if(ret){
- printk(KERN_WARNING "Unable to register led %s\n",p->name);
- }
- }
- /* end of new code */
- PDEBUG("All devices loaded\n");
- return 0 ;
-}
-
-static int led_remove(struct platform_device *dev){
- struct plat_led_port *p = dev->dev.platform_data;
- int i;
- PDEBUG("Removing leds\n");
- for (i = 0; p->name!=NULL ; p++, i++) {
- PDEBUG("Remove led %d\n",i);
- free_all(p);
- }
- return 0;
-}
-
-static int free_all(struct plat_led_port *dev){
- struct led_dev *sdev = &led_device[dev->num];
-
- PDEBUG("Unregister %s, number %d\n",dev->name,dev->num);
-
- /* delete the cdev structure */
- cdev_del(&sdev->cdev);
- PDEBUG("%s:cdev deleted\n",dev->name);
-
- /* free major and minor number */
- unregister_chrdev_region(sdev->devno,1);
- printk(KERN_INFO "%s: Led deleted\n",dev->name);
- return 0;
-}
-
-module_init(led_init);
-module_exit(led_exit);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-09-11 15:08:31
|
Revision: 880
http://armadeus.svn.sourceforge.net/armadeus/?rev=880&view=rev
Author: artemys
Date: 2008-09-11 15:08:41 +0000 (Thu, 11 Sep 2008)
Log Message:
-----------
[LINUX] do some cleanup in Wb_led driver
Modified Paths:
--------------
trunk/target/linux/modules/fpga/others/Wb_led/Makefile
trunk/target/linux/modules/fpga/others/Wb_led/g_led.c
trunk/target/linux/modules/fpga/others/Wb_led/s_led.c
Modified: trunk/target/linux/modules/fpga/others/Wb_led/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/Makefile 2008-09-11 08:50:35 UTC (rev 879)
+++ trunk/target/linux/modules/fpga/others/Wb_led/Makefile 2008-09-11 15:08:41 UTC (rev 880)
@@ -33,6 +33,8 @@
clean:
rm -f *.*o \
rm -f Module.symvers
-
+ rm -rf .*.cmd
+ rm -f *.mod.c
+
endif
Modified: trunk/target/linux/modules/fpga/others/Wb_led/g_led.c
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/g_led.c 2008-09-11 08:50:35 UTC (rev 879)
+++ trunk/target/linux/modules/fpga/others/Wb_led/g_led.c 2008-09-11 15:08:41 UTC (rev 880)
@@ -21,10 +21,6 @@
**********************************************************************
*/
-
-#ifndef __G_LED_H__
-#define __G_LED_H__
-
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#include <linux/config.h>
@@ -56,7 +52,6 @@
/* led */
#include "led.h"
-#endif
/* for debugging messages*/
#define LED_DEBUG
@@ -80,39 +75,7 @@
#define LED_NUMBER 2
-static int led_probe(struct platform_device *plat_led_device);
-static int led_remove(struct platform_device *plat_led_device);
-static struct platform_driver plat_led_driver = {
- .probe = led_probe,
- .remove = led_remove,
- .driver = {
- .name = "led",
- .owner = THIS_MODULE,
- },
-};
-
-/************************************
- * module init and exit
- ***********************************/
-
-static int __init led_init(void){
- int ret;
- PDEBUG("init Led platform driver\n");
- PDEBUG("Platform driver name %s\n",plat_led_driver.driver.name);
- ret = platform_driver_register(&plat_led_driver);
- if(ret){
- printk(KERN_ERR "Platform driver register error\n");
- return ret;
- }
- return 0;
-}
-
-static void __exit led_exit(void){
- PDEBUG("g_led exit function \n");
- platform_driver_unregister(&plat_led_driver);
-}
-
/*************************/
/* main device structure */
/*************************/
@@ -220,19 +183,24 @@
/* ******************************
* Init and release functions
* ******************************/
-int led_release(struct inode *inode, struct file *filp){
+int led_release(struct inode *inode, struct file *filp)
+{
struct led_dev *dev;
+
dev = container_of(inode->i_cdev,struct led_dev,cdev);
PDEBUG( "%s: released\n",dev->name);
filp->private_data=NULL;
+
return 0;
}
-int register_led(struct plat_led_port *dev){
+int register_led(struct plat_led_port *dev)
+{
int result = 0; /* error return */
int led_major,led_minor;
u16 data;
struct led_dev *sdev = &led_device[dev->num];
+
PDEBUG("Register %d led\n",dev->num);
/* major and minor number */
led_major = 253;
@@ -242,57 +210,57 @@
sdev->membase = dev->membase;
/* name and address of the instance */
- sdev->name = (char *)kmalloc((1+strlen(dev->name))*sizeof(char),GFP_KERNEL);
- if(sdev->name == NULL){
+ sdev->name = (char *)kmalloc((1+strlen(dev->name))*sizeof(char), GFP_KERNEL);
+ if (sdev->name == NULL) {
printk("Kmalloc name space error\n");
goto error;
}
- if(strncpy(sdev->name,dev->name,1+strlen(dev->name)) < 0){
+ if (strncpy(sdev->name,dev->name,1+strlen(dev->name)) < 0) {
printk("copy error");
goto error;
}
/* Get the major and minor device numbers */
PDEBUG("%s:Get the major and minor device numbers\n",dev->name);
- if(led_major){
- sdev->devno = MKDEV(led_major,led_minor);
+ if (led_major) {
+ sdev->devno = MKDEV(led_major, led_minor);
result = register_chrdev_region(sdev->devno, 1,dev->name);
- }else{
- result = alloc_chrdev_region(&sdev->devno,led_minor,1,dev->name);
+ } else {
+ result = alloc_chrdev_region(&sdev->devno, led_minor, 1, dev->name);
led_major = MAJOR(sdev->devno);
}
printk(KERN_INFO "%s: MAJOR: %d MINOR: %d\n",dev->name,MAJOR(sdev->devno),MINOR(sdev->devno));
- if(result < 0){
+ if (result < 0) {
printk(KERN_WARNING "%s: can't get major %d\n",dev->name,led_major);
goto error;
}
/* Init the cdev structure */
- PDEBUG("%s:Init the cdev structure\n",dev->name);
- cdev_init(&sdev->cdev,&led_fops);
+ PDEBUG("%s:Init the cdev structure\n", dev->name);
+ cdev_init(&sdev->cdev, &led_fops);
sdev->cdev.owner = THIS_MODULE;
sdev->cdev.ops = &led_fops;
/* Add the device to the kernel, connecting cdev to major/minor number */
- PDEBUG("%s:Add the device to the kernel, connecting cdev to major/minor number \n",dev->name);
- result = cdev_add(&sdev->cdev,sdev->devno,1);
- if(result){
- printk(KERN_WARNING "%s: can't add cdev\n",dev->name);
+ PDEBUG("%s:Add the device to the kernel, connecting cdev to major/minor number \n", dev->name);
+ result = cdev_add(&sdev->cdev, sdev->devno, 1);
+ if (result) {
+ printk(KERN_WARNING "%s: can't add cdev\n", dev->name);
goto error;
}
/* initialize led value */
data=1;
iowrite16(data,sdev->fpga_virtual_base_address + sdev->membase);
- PDEBUG("Wrote %x at %x\n",data,sdev->membase);
+ PDEBUG("Wrote %x at %x\n", data, sdev->membase);
/* OK module inserted ! */
- printk(KERN_INFO "Led module %s insered\n",dev->name);
+ printk(KERN_INFO "Led module %s insered\n", dev->name);
return 0;
error:
- printk(KERN_ERR "%s: not inserted\n",dev->name);
+ printk(KERN_ERR "%s: not inserted\n", dev->name);
free_all(dev);
return result;
}
@@ -300,18 +268,18 @@
/**********************************
* driver probe
**********************************/
-static int led_probe(struct platform_device *dev){
+static int led_probe(struct platform_device *pdev)
+{
+ /* new code for led with platform device */
+ struct plat_led_port *p = pdev->dev.platform_data;
+ int ret, i;
- /* new code for led with platform device */
- struct plat_led_port *p = dev->dev.platform_data;
- int ret,i;
-
PDEBUG("Led probing\n");
/* register each led in plat_led_port tab */
for (i = 0; p->name!=NULL ; p++, i++) {
PDEBUG("%s:register led number %d\n",p->name,i);
ret = register_led(p);
- if(ret){
+ if (ret) {
printk(KERN_WARNING "Unable to register led %s\n",p->name);
}
}
@@ -320,18 +288,22 @@
return 0 ;
}
-static int led_remove(struct platform_device *dev){
- struct plat_led_port *p = dev->dev.platform_data;
+static int __devexit led_remove(struct platform_device *pdev)
+{
+ struct plat_led_port *p = pdev->dev.platform_data;
int i;
+
PDEBUG("Removing leds\n");
for (i = 0; p->name!=NULL ; p++, i++) {
PDEBUG("Remove led %d\n",i);
free_all(p);
}
- return 0;
+
+ return 0;
}
-static int free_all(struct plat_led_port *dev){
+static int free_all(struct plat_led_port *dev)
+{
struct led_dev *sdev = &led_device[dev->num];
PDEBUG("Unregister %s, number %d\n",dev->name,dev->num);
@@ -343,9 +315,37 @@
/* free major and minor number */
unregister_chrdev_region(sdev->devno,1);
printk(KERN_INFO "%s: Led deleted\n",dev->name);
+
return 0;
}
+static struct platform_driver plat_led_driver = {
+ .probe = led_probe,
+ .remove = __devexit_p(led_remove),
+ .driver = {
+ .name = "led",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init led_init(void)
+{
+ int ret;
+
+ PDEBUG("Platform driver name %s\n", plat_led_driver.driver.name);
+ ret = platform_driver_register(&plat_led_driver);
+ if (ret) {
+ printk(KERN_ERR "Platform driver register error\n");
+ return ret;
+ }
+ return 0;
+}
+
+static void __exit led_exit(void)
+{
+ platform_driver_unregister(&plat_led_driver);
+}
+
module_init(led_init);
module_exit(led_exit);
Modified: trunk/target/linux/modules/fpga/others/Wb_led/s_led.c
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/s_led.c 2008-09-11 08:50:35 UTC (rev 879)
+++ trunk/target/linux/modules/fpga/others/Wb_led/s_led.c 2008-09-11 15:08:41 UTC (rev 880)
@@ -21,9 +21,6 @@
**********************************************************************
*/
-#ifndef __S_LED_H__
-#define __S_LED_H__
-
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#include <linux/config.h>
@@ -33,51 +30,12 @@
#include <linux/init.h>
#include <linux/module.h>
-/* for file operations */
-#include <linux/fs.h>
-#include <linux/cdev.h>
-
-/* copy_to_user function */
-#include <asm/uaccess.h>
-
-/* request_mem_region */
-#include <linux/ioport.h>
-
-/* readw() writew() */
-#include <asm/io.h>
-
-/* hardware addresses */
-#include <asm/hardware.h>
-
/* for platform device */
#include <linux/platform_device.h>
-#endif
-
-/* for debugging messages*/
-#define LED_DEBUG
-
-#undef PDEBUG
-#ifdef LED_DEBUG
-# ifdef __KERNEL__
- /* for kernel spage */
-# define PDEBUG(fmt,args...) printk(KERN_DEBUG "LED : " fmt, ##args)
-# else
- /* for user space */
-# define PDEBUG(fmt,args...) printk(stderr, fmt, ##args)
-# endif
-#else
-# define PDEBUG(fmt,args...) /* no debbuging message */
-#endif
-
-
-#define FPGA_BASE_ADDR IMX_CS1_PHYS
-#define FPGA_MEM_SIZE IMX_CS1_SIZE
-
-#define LED_NUMBER 2
-
#include"led.h"
+
static struct plat_led_port plat_led_data[] = {
{
.name = "led0",
@@ -100,12 +58,13 @@
},
};
-static int __init sled_init(void){
- PDEBUG("Driver registered\n");
+static int __init sled_init(void)
+{
return platform_device_register(&plat_led_device);
}
-static void __exit sled_exit(void){
+static void __exit sled_exit(void)
+{
platform_device_unregister(&plat_led_device);
}
@@ -113,6 +72,6 @@
module_exit(sled_exit);
MODULE_AUTHOR("Fabien Marteau <fab...@ar...>");
-MODULE_DESCRIPTION("Driver to blink blink some led");
+MODULE_DESCRIPTION("Driver to blink blink some leds");
MODULE_LICENSE("GPL");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <Fa...@us...> - 2008-09-11 08:50:25
|
Revision: 879
http://armadeus.svn.sourceforge.net/armadeus/?rev=879&view=rev
Author: FabM
Date: 2008-09-11 08:50:35 +0000 (Thu, 11 Sep 2008)
Log Message:
-----------
[DRIVER] wb_led cleaning
Modified Paths:
--------------
trunk/target/linux/modules/fpga/others/Wb_led/Makefile
trunk/target/linux/modules/fpga/others/Wb_led/led.h
Added Paths:
-----------
trunk/target/linux/modules/fpga/others/Wb_led/g_led.c
trunk/target/linux/modules/fpga/others/Wb_led/s_led.c
Modified: trunk/target/linux/modules/fpga/others/Wb_led/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/Makefile 2008-09-10 14:04:36 UTC (rev 878)
+++ trunk/target/linux/modules/fpga/others/Wb_led/Makefile 2008-09-11 08:50:35 UTC (rev 879)
@@ -11,7 +11,7 @@
ifneq ($(KERNELRELEASE),)
-obj-$(CONFIG_ARMADEUS_LED_DRIVER) += led.o
+obj-$(CONFIG_ARMADEUS_LED_DRIVER) += s_led.o g_led.o
# Part executed when called from standard make in this directory:
# (preferably use Makefile in parent directory)
@@ -22,7 +22,8 @@
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
- -cp led.ko /tftpboot/
+ -cp g_led.ko /tftpboot/
+ -cp s_led.ko /tftpboot/
test:
~/armadeus/buildroot/build_arm/staging_dir/bin/arm-linux-gcc -Wall testled.c -o testled
Added: trunk/target/linux/modules/fpga/others/Wb_led/g_led.c
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/g_led.c (rev 0)
+++ trunk/target/linux/modules/fpga/others/Wb_led/g_led.c 2008-09-11 08:50:35 UTC (rev 879)
@@ -0,0 +1,355 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ * Generic driver for Wishbone led IP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+
+
+#ifndef __G_LED_H__
+#define __G_LED_H__
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+
+/* form module/drivers */
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* for file operations */
+#include <linux/fs.h>
+#include <linux/cdev.h>
+
+/* copy_to_user function */
+#include <asm/uaccess.h>
+
+/* request_mem_region */
+#include <linux/ioport.h>
+
+/* readw() writew() */
+#include <asm/io.h>
+
+/* hardware addresses */
+#include <asm/hardware.h>
+
+/* for platform device */
+#include <linux/platform_device.h>
+
+/* led */
+#include "led.h"
+
+#endif
+
+/* for debugging messages*/
+#define LED_DEBUG
+
+#undef PDEBUG
+#ifdef LED_DEBUG
+# ifdef __KERNEL__
+ /* for kernel spage */
+# define PDEBUG(fmt,args...) printk(KERN_DEBUG "LED : " fmt, ##args)
+# else
+ /* for user space */
+# define PDEBUG(fmt,args...) printk(stderr, fmt, ##args)
+# endif
+#else
+# define PDEBUG(fmt,args...) /* no debbuging message */
+#endif
+
+
+#define FPGA_BASE_ADDR IMX_CS1_PHYS
+#define FPGA_MEM_SIZE IMX_CS1_SIZE
+
+#define LED_NUMBER 2
+
+static int led_probe(struct platform_device *plat_led_device);
+static int led_remove(struct platform_device *plat_led_device);
+
+static struct platform_driver plat_led_driver = {
+ .probe = led_probe,
+ .remove = led_remove,
+ .driver = {
+ .name = "led",
+ .owner = THIS_MODULE,
+ },
+};
+
+/************************************
+ * module init and exit
+ ***********************************/
+
+static int __init led_init(void){
+ int ret;
+ PDEBUG("init Led platform driver\n");
+ PDEBUG("Platform driver name %s\n",plat_led_driver.driver.name);
+ ret = platform_driver_register(&plat_led_driver);
+ if(ret){
+ printk(KERN_ERR "Platform driver register error\n");
+ return ret;
+ }
+ return 0;
+}
+
+static void __exit led_exit(void){
+ PDEBUG("g_led exit function \n");
+ platform_driver_unregister(&plat_led_driver);
+}
+
+/*************************/
+/* main device structure */
+/*************************/
+struct led_dev{
+ char *name; /* the name of the instance */
+ struct cdev cdev; /* Char device structure */
+ void * fpga_virtual_base_address; /* fpga register base address*/
+ unsigned int membase; /* base address for instance relative to
+ fpga_virtual_base_address */
+ dev_t devno; /* to store Major and minor numbers */
+};
+
+static struct led_dev led_device[LED_NUMBER];
+
+/******************************/
+/* to read write led register */
+/******************************/
+ssize_t led_read(struct file *fildes, char __user *buff,
+ size_t count, loff_t *offp);
+
+ssize_t led_write(struct file *fildes, const char __user *
+ buff,size_t count, loff_t *offp);
+int led_open(struct inode *inode, struct file *filp);
+
+int led_release(struct inode *, struct file *filp);
+
+static struct file_operations led_fops = {
+ .owner = THIS_MODULE,
+ .read = led_read,
+ .write = led_write,
+ .open = led_open,
+ .release = led_release,
+};
+
+/****************************
+ * personnal functions
+ ***************************/
+
+static int free_all(struct plat_led_port *);
+
+
+/***********************************
+ * characters file /dev operations
+ * *********************************/
+ssize_t led_read(struct file *fildes, char __user *buff,
+ size_t count, loff_t *offp){
+ struct led_dev *sdev = fildes->private_data;
+ u16 data=0;
+ PDEBUG("Read value\n");
+ if(*offp != 0 ){ /* offset must be 0 */
+ PDEBUG("offset %d\n",(int)*offp);
+ return 0;
+ }
+
+ PDEBUG("count %d\n",count);
+ if(count > 2){ /* 16bits max*/
+ count = 2;
+ }
+
+ data = ioread16(sdev->fpga_virtual_base_address + sdev->membase);
+ PDEBUG("Read %d at %x\n",data,sdev->membase);
+
+ /* return data for user */
+ if(copy_to_user(buff,&data,count)){
+ printk(KERN_WARNING "read : copy to user data error\n");
+ return -EFAULT;
+ }
+ return count;
+}
+
+ssize_t led_write(struct file *fildes, const char __user *
+ buff,size_t count, loff_t *offp){
+ struct led_dev *sdev = fildes->private_data;
+ u16 data=0;
+
+ if(*offp != 0){ /* offset must be 0 */
+ PDEBUG("offset %d\n",(int)*offp);
+ return 0;
+ }
+
+ PDEBUG("count %d\n",count);
+ if(count > 2){ /* 16 bits max)*/
+ count = 2;
+ }
+
+ if(copy_from_user(&data,buff,count)){
+ printk(KERN_WARNING "write : copy from user error\n");
+ return -EFAULT;
+ }
+
+ PDEBUG("Write %d at %x\n",data,sdev->membase);
+ iowrite16(data,sdev->fpga_virtual_base_address + sdev->membase);
+
+ return count;
+}
+
+
+int led_open(struct inode *inode, struct file *filp){
+ /* Allocate and fill any data structure to be put in filp->private_data */
+ filp->private_data = container_of(inode->i_cdev,struct led_dev, cdev);
+ PDEBUG( "Led opened\n");
+ return 0;
+}
+
+/* ******************************
+ * Init and release functions
+ * ******************************/
+int led_release(struct inode *inode, struct file *filp){
+ struct led_dev *dev;
+ dev = container_of(inode->i_cdev,struct led_dev,cdev);
+ PDEBUG( "%s: released\n",dev->name);
+ filp->private_data=NULL;
+ return 0;
+}
+
+int register_led(struct plat_led_port *dev){
+ int result = 0; /* error return */
+ int led_major,led_minor;
+ u16 data;
+ struct led_dev *sdev = &led_device[dev->num];
+ PDEBUG("Register %d led\n",dev->num);
+ /* major and minor number */
+ led_major = 253;
+ led_minor = dev->num ;
+
+ sdev->fpga_virtual_base_address = (void*)IMX_CS1_VIRT;
+ sdev->membase = dev->membase;
+
+ /* name and address of the instance */
+ sdev->name = (char *)kmalloc((1+strlen(dev->name))*sizeof(char),GFP_KERNEL);
+ if(sdev->name == NULL){
+ printk("Kmalloc name space error\n");
+ goto error;
+ }
+ if(strncpy(sdev->name,dev->name,1+strlen(dev->name)) < 0){
+ printk("copy error");
+ goto error;
+ }
+
+ /* Get the major and minor device numbers */
+ PDEBUG("%s:Get the major and minor device numbers\n",dev->name);
+ if(led_major){
+ sdev->devno = MKDEV(led_major,led_minor);
+ result = register_chrdev_region(sdev->devno, 1,dev->name);
+ }else{
+ result = alloc_chrdev_region(&sdev->devno,led_minor,1,dev->name);
+ led_major = MAJOR(sdev->devno);
+ }
+
+ printk(KERN_INFO "%s: MAJOR: %d MINOR: %d\n",dev->name,MAJOR(sdev->devno),MINOR(sdev->devno));
+ if(result < 0){
+ printk(KERN_WARNING "%s: can't get major %d\n",dev->name,led_major);
+ goto error;
+ }
+
+ /* Init the cdev structure */
+ PDEBUG("%s:Init the cdev structure\n",dev->name);
+ cdev_init(&sdev->cdev,&led_fops);
+ sdev->cdev.owner = THIS_MODULE;
+ sdev->cdev.ops = &led_fops;
+
+ /* Add the device to the kernel, connecting cdev to major/minor number */
+ PDEBUG("%s:Add the device to the kernel, connecting cdev to major/minor number \n",dev->name);
+ result = cdev_add(&sdev->cdev,sdev->devno,1);
+ if(result){
+ printk(KERN_WARNING "%s: can't add cdev\n",dev->name);
+ goto error;
+ }
+
+ /* initialize led value */
+ data=1;
+ iowrite16(data,sdev->fpga_virtual_base_address + sdev->membase);
+ PDEBUG("Wrote %x at %x\n",data,sdev->membase);
+
+ /* OK module inserted ! */
+ printk(KERN_INFO "Led module %s insered\n",dev->name);
+ return 0;
+
+error:
+ printk(KERN_ERR "%s: not inserted\n",dev->name);
+ free_all(dev);
+ return result;
+}
+
+/**********************************
+ * driver probe
+ **********************************/
+static int led_probe(struct platform_device *dev){
+
+ /* new code for led with platform device */
+ struct plat_led_port *p = dev->dev.platform_data;
+ int ret,i;
+
+ PDEBUG("Led probing\n");
+ /* register each led in plat_led_port tab */
+ for (i = 0; p->name!=NULL ; p++, i++) {
+ PDEBUG("%s:register led number %d\n",p->name,i);
+ ret = register_led(p);
+ if(ret){
+ printk(KERN_WARNING "Unable to register led %s\n",p->name);
+ }
+ }
+ /* end of new code */
+ PDEBUG("All devices loaded\n");
+ return 0 ;
+}
+
+static int led_remove(struct platform_device *dev){
+ struct plat_led_port *p = dev->dev.platform_data;
+ int i;
+ PDEBUG("Removing leds\n");
+ for (i = 0; p->name!=NULL ; p++, i++) {
+ PDEBUG("Remove led %d\n",i);
+ free_all(p);
+ }
+ return 0;
+}
+
+static int free_all(struct plat_led_port *dev){
+ struct led_dev *sdev = &led_device[dev->num];
+
+ PDEBUG("Unregister %s, number %d\n",dev->name,dev->num);
+
+ /* delete the cdev structure */
+ cdev_del(&sdev->cdev);
+ PDEBUG("%s:cdev deleted\n",dev->name);
+
+ /* free major and minor number */
+ unregister_chrdev_region(sdev->devno,1);
+ printk(KERN_INFO "%s: Led deleted\n",dev->name);
+ return 0;
+}
+
+module_init(led_init);
+module_exit(led_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabien Marteau <fab...@ar...> - ARMadeus Systems");
+MODULE_DESCRIPTION("Led device driver");
+
Modified: trunk/target/linux/modules/fpga/others/Wb_led/led.h
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/led.h 2008-09-10 14:04:36 UTC (rev 878)
+++ trunk/target/linux/modules/fpga/others/Wb_led/led.h 2008-09-11 08:50:35 UTC (rev 879)
@@ -3,7 +3,7 @@
*
* (c) Copyright 2007 Armadeus project
* Fabien Marteau <fab...@ar...>
- * Driver for Wb_led IP
+ * Driver for Wishbone led IP
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,13 +34,6 @@
#include <linux/init.h>
#include <linux/module.h>
-/* linux device model
-*#include <linux/kobject.h>
-*#include <linux/sysfs.h>
-*#include <linux/sysdev.h>
-*#include <linux/device.h>
-*/
-
/* for file operations */
#include <linux/fs.h>
#include <linux/cdev.h>
@@ -91,116 +84,4 @@
unsigned int membase; /* ioremap base address */
};
-static struct plat_led_port plat_led_data[] = {
- {
- .name = "led0",
- .num = 0,
- .membase = 0x04
- },
- {
- .name = "led1",
- .num = 1,
- .membase = 0x06
- },
- {
- .name = NULL
- },
-};
-static struct platform_device plat_led_device = {
- .name = "led",
- .id = 0,
- .dev = {
- .platform_data = plat_led_data
- },
-};
-
-
-static int led_probe(struct platform_device *plat_led_device);
-static int led_remove(struct platform_device *plat_led_device);
-
-static struct platform_driver plat_led_driver = {
- .probe = led_probe,
- .remove = led_remove,
- .driver = {
- .name = "led",
- .owner = THIS_MODULE,
- },
-};
-
-/************************************
- * module init and exit
- ***********************************/
-
-static int __init led_init(void){
- int ret;
- PDEBUG("init Led platform driver\n");
- PDEBUG("Platform driver name %s\n",plat_led_driver.driver.name);
- ret = platform_driver_register(&plat_led_driver);
- if(ret){
- printk(KERN_ERR "Platform driver register error\n");
- return ret;
- }
- PDEBUG("Driver registered\n");
- ret = platform_device_add(&plat_led_device);
- if(ret){
- printk(KERN_ERR "Platform device adding problem\n");
- return ret;
- }
- return 0;
-}
-
-static void __exit led_exit(void){
- PDEBUG("Exit function \n");
- platform_driver_unregister(&plat_led_driver);
- PDEBUG("driver unregistered\n");
- //platform_device_unregister(&plat_led_device);
- //PDEBUG("device unregistered\n");
-
-}
-
-/*************************/
-/* main device structure */
-/*************************/
-struct led_dev{
- char *name; /* the name of the instance */
- struct cdev cdev; /* Char device structure */
- void * fpga_virtual_base_address; /* fpga register base address*/
- unsigned int membase; /* base address for instance relative to
- fpga_virtual_base_address */
- dev_t devno; /* to store Major and minor numbers */
-};
-
-static struct led_dev led_device[LED_NUMBER];
-
-/******************************/
-/* to read write led register */
-/******************************/
-ssize_t led_read(struct file *fildes, char __user *buff,
- size_t count, loff_t *offp);
-
-ssize_t led_write(struct file *fildes, const char __user *
- buff,size_t count, loff_t *offp);
-int led_open(struct inode *inode, struct file *filp);
-
-int led_release(struct inode *, struct file *filp);
-
-static struct file_operations led_fops = {
- .owner = THIS_MODULE,
- .read = led_read,
- .write = led_write,
- .open = led_open,
- .release = led_release,
-};
-
-/****************************
- * personnal functions
- ***************************/
-
-static int free_all(struct plat_led_port *);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Fabien Marteau <fab...@ar...> - ARMadeus Systems");
-MODULE_DESCRIPTION("Led device driver");
-
-
Added: trunk/target/linux/modules/fpga/others/Wb_led/s_led.c
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/s_led.c (rev 0)
+++ trunk/target/linux/modules/fpga/others/Wb_led/s_led.c 2008-09-11 08:50:35 UTC (rev 879)
@@ -0,0 +1,118 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ * Specific led driver for generic led driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+
+#ifndef __S_LED_H__
+#define __S_LED_H__
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+
+/* form module/drivers */
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* for file operations */
+#include <linux/fs.h>
+#include <linux/cdev.h>
+
+/* copy_to_user function */
+#include <asm/uaccess.h>
+
+/* request_mem_region */
+#include <linux/ioport.h>
+
+/* readw() writew() */
+#include <asm/io.h>
+
+/* hardware addresses */
+#include <asm/hardware.h>
+
+/* for platform device */
+#include <linux/platform_device.h>
+
+#endif
+
+/* for debugging messages*/
+#define LED_DEBUG
+
+#undef PDEBUG
+#ifdef LED_DEBUG
+# ifdef __KERNEL__
+ /* for kernel spage */
+# define PDEBUG(fmt,args...) printk(KERN_DEBUG "LED : " fmt, ##args)
+# else
+ /* for user space */
+# define PDEBUG(fmt,args...) printk(stderr, fmt, ##args)
+# endif
+#else
+# define PDEBUG(fmt,args...) /* no debbuging message */
+#endif
+
+
+#define FPGA_BASE_ADDR IMX_CS1_PHYS
+#define FPGA_MEM_SIZE IMX_CS1_SIZE
+
+#define LED_NUMBER 2
+
+#include"led.h"
+
+static struct plat_led_port plat_led_data[] = {
+ {
+ .name = "led0",
+ .num = 0,
+ .membase = 0x04
+ },
+ {
+ .name = "led1",
+ .num = 1,
+ .membase = 0x06
+ },
+ { },
+};
+
+static struct platform_device plat_led_device = {
+ .name = "led",
+ .id = 0,
+ .dev = {
+ .platform_data = plat_led_data
+ },
+};
+
+static int __init sled_init(void){
+ PDEBUG("Driver registered\n");
+ return platform_device_register(&plat_led_device);
+}
+
+static void __exit sled_exit(void){
+ platform_device_unregister(&plat_led_device);
+}
+
+module_init(sled_init);
+module_exit(sled_exit);
+
+MODULE_AUTHOR("Fabien Marteau <fab...@ar...>");
+MODULE_DESCRIPTION("Driver to blink blink some led");
+MODULE_LICENSE("GPL");
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-09-10 14:04:26
|
Revision: 878
http://armadeus.svn.sourceforge.net/armadeus/?rev=878&view=rev
Author: artemys
Date: 2008-09-10 14:04:36 +0000 (Wed, 10 Sep 2008)
Log Message:
-----------
[LINUX_DEBUG] Add i.MX27 support to imxregs tool
Modified Paths:
--------------
branches/apf2/target/linux/debug/imxregs/Makefile
branches/apf2/target/linux/debug/imxregs/imxregs.c
branches/apf2/target/linux/debug/imxregs/imxregs.h
Added Paths:
-----------
branches/apf2/target/linux/debug/imxregs/README
branches/apf2/target/linux/debug/imxregs/definitions.h
branches/apf2/target/linux/debug/imxregs/imx27regs.h
branches/apf2/target/linux/debug/imxregs/txt_copy_of_pdf_to_include.sh
Modified: branches/apf2/target/linux/debug/imxregs/Makefile
===================================================================
--- branches/apf2/target/linux/debug/imxregs/Makefile 2008-09-09 20:40:58 UTC (rev 877)
+++ branches/apf2/target/linux/debug/imxregs/Makefile 2008-09-10 14:04:36 UTC (rev 878)
@@ -1,9 +1,15 @@
+ifeq ($(CC),cc)
+ CC=arm-linux-gcc
+endif
-all: imxregs
+all: imxregs imx27regs
-imxregs: imxregs.c imxregs.h
- arm-linux-gcc imxregs.c -o $@
-
+imxregs: imxregs.c imxregs.h definitions.h
+ $(CC) imxregs.c -o $@
+
+imx27regs: imxregs.c imx27regs.h definitions.h
+ $(CC) -DIMX27 imxregs.c -o $@
+
clean:
rm -f *.o
- rm -f imxregs
+ rm -f imxregs imx27regs
Added: branches/apf2/target/linux/debug/imxregs/README
===================================================================
--- branches/apf2/target/linux/debug/imxregs/README (rev 0)
+++ branches/apf2/target/linux/debug/imxregs/README 2008-09-10 14:04:36 UTC (rev 878)
@@ -0,0 +1,3 @@
+To compile:
+ $ make CC=../../../../buildroot/build_arm/staging_dir/bin/arm-linux-gcc
+
Added: branches/apf2/target/linux/debug/imxregs/definitions.h
===================================================================
--- branches/apf2/target/linux/debug/imxregs/definitions.h (rev 0)
+++ branches/apf2/target/linux/debug/imxregs/definitions.h 2008-09-10 14:04:36 UTC (rev 878)
@@ -0,0 +1,36 @@
+/*
+ * definitions.h - imxregs common definitions
+ *
+ * Copyright (C) 2008 armadeus systems
+ * Author: Julien Boibessot
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+typedef unsigned int u32;
+
+struct reg_info {
+ char *name;
+ u32 addr;
+ int shift;
+ u32 mask;
+ char type;
+ char *desc;
+};
+
+// Size of mmapping:
+#define MAP_SIZE 4096
+#define MAP_MASK ( MAP_SIZE - 1 )
Added: branches/apf2/target/linux/debug/imxregs/imx27regs.h
===================================================================
--- branches/apf2/target/linux/debug/imxregs/imx27regs.h (rev 0)
+++ branches/apf2/target/linux/debug/imxregs/imx27regs.h 2008-09-10 14:04:36 UTC (rev 878)
@@ -0,0 +1,1297 @@
+/*
+ * imx27regs.h - i.MX27 registers definition
+ *
+ * Copyright (C) 2008 armadeus systems
+ * Derivated from pxaregs (c) Copyright 2002 by M&N Logistik-Loesungen Online GmbH
+ * Author: Julien Boibessot
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "definitions.h"
+
+static struct reg_info regs[] =
+{
+// AIPI1
+{ "PSR0", 0x10000000, 0, 0xffffffff, 'x', "Peripheral Size Register 0" },
+{ "PSR1", 0x10000004, 0, 0xffffffff, 'x', "Peripheral Size Register 1" },
+{ "PAR", 0x10000008, 0, 0xffffffff, 'x', "Peripheral Access Register" },
+{ "AAOR", 0x1000000C, 0, 0xffffffff, 'x', "Atomic Access Only Register" },
+// DMAC
+{ "DCR", 0x10001000, 0, 0xffffffff, 'x', "DMA Control Register" },
+{ "DISR", 0x10001004, 0, 0xffffffff, 'x', "DMA Interrupt Status Register" },
+{ "DIMR", 0x10001008, 0, 0xffffffff, 'x', "DMA Interrupt Mask Register" },
+{ "DBTOSR", 0x1000100C, 0, 0xffffffff, 'x', "DMA Burst Time-Out Status Register" },
+{ "DRTOSR", 0x10001010, 0, 0xffffffff, 'x', "DMA Request Time-Out Status Register" },
+{ "DSESR", 0x10001014, 0, 0xffffffff, 'x', "DMA Transfer Error Status Register" },
+{ "DBOSR", 0x10001018, 0, 0xffffffff, 'x', "DMA Buffer Overflow Status Register" },
+{ "DBTOCR", 0x1000101C, 0, 0xffffffff, 'x', "DMA Burst Time-Out Control Register" },
+{ "WSRA", 0x10001040, 0, 0xffffffff, 'x', "W-Size Register A" },
+{ "XSRA", 0x10001044, 0, 0xffffffff, 'x', "X-Size Register A" },
+{ "YSRA", 0x10001048, 0, 0xffffffff, 'x', "Y-Size Register A" },
+{ "WSRB", 0x1000104C, 0, 0xffffffff, 'x', "W-Size Register B" },
+{ "XSRB", 0x10001050, 0, 0xffffffff, 'x', "X-Size Register B" },
+{ "YSRB", 0x10001054, 0, 0xffffffff, 'x', "Y-Size Register B" },
+{ "SAR0", 0x10001080, 0, 0xffffffff, 'x', "Channel 0 Source Address Register" },
+{ "DAR0", 0x10001084, 0, 0xffffffff, 'x', "Channel 0 Destination Address Register" },
+{ "CNTR0", 0x10001088, 0, 0xffffffff, 'x', "Channel 0 Count Register" },
+{ "CCR0", 0x1000108C, 0, 0xffffffff, 'x', "Channel 0 Control Register" },
+{ "RSSR0", 0x10001090, 0, 0xffffffff, 'x', "Channel 0 Request Source Select Register" },
+{ "BLR0", 0x10001094, 0, 0xffffffff, 'x', "Channel 0 Burst Length Register" },
+{ "RTOR0", 0x10001098, 0, 0xffffffff, 'x', "Channel 0 Request Time-Out Register" },
+{ "BUCR0", 0x10001098, 0, 0xffffffff, 'x', "Channel 0 Bus Utilization Control Register" },
+{ "CCNR0", 0x1000109C, 0, 0xffffffff, 'x', "Channel 0 Channel Counter Register" },
+{ "SAR1", 0x100010C0, 0, 0xffffffff, 'x', "Channel 1 Source Address Register" },
+{ "DAR1", 0x100010C4, 0, 0xffffffff, 'x', "Channel 1 Destination Address Register" },
+{ "CNTR1", 0x100010C8, 0, 0xffffffff, 'x', "Channel 1 Count Register" },
+{ "CCR1", 0x100010CC, 0, 0xffffffff, 'x', "Channel 1 Control Register" },
+{ "RSSR1", 0x100010D0, 0, 0xffffffff, 'x', "Channel 1 Request Source Select Register" },
+{ "BLR1", 0x100010D4, 0, 0xffffffff, 'x', "Channel 1 Burst Length Register" },
+{ "RTOR1", 0x100010D8, 0, 0xffffffff, 'x', "Channel 1 Request Time-Out Register" },
+{ "BUCR1", 0x100010D8, 0, 0xffffffff, 'x', "Channel 1 Bus Utilization Control Register" },
+{ "CCNR1", 0x100010DC, 0, 0xffffffff, 'x', "Channel 1 Channel Counter Register" },
+{ "SAR2", 0x10001100, 0, 0xffffffff, 'x', "Channel 2 Source Address Register" },
+{ "DAR2", 0x10001104, 0, 0xffffffff, 'x', "Channel 2 Destination Address Register" },
+{ "CNTR2", 0x10001108, 0, 0xffffffff, 'x', "Channel 2 Count Register" },
+{ "CCR2", 0x1000110C, 0, 0xffffffff, 'x', "Channel 2 Control Register" },
+{ "RSSR2", 0x10001110, 0, 0xffffffff, 'x', "Channel 2 Request Source Select Register" },
+{ "BLR2", 0x10001114, 0, 0xffffffff, 'x', "Channel 2 Burst Length Register" },
+{ "RTOR2", 0x10001118, 0, 0xffffffff, 'x', "Channel 2 Request Time-Out Register" },
+{ "BUCR2", 0x10001118, 0, 0xffffffff, 'x', "Channel 2 Bus Utilization Control Register" },
+{ "CCNR2", 0x1000111C, 0, 0xffffffff, 'x', "Channel 2 Channel Counter Register" },
+{ "SAR3", 0x10001140, 0, 0xffffffff, 'x', "Channel 3 Source Address Register" },
+{ "DAR3", 0x10001144, 0, 0xffffffff, 'x', "Channel 3 Destination Address Register" },
+{ "CNTR3", 0x10001148, 0, 0xffffffff, 'x', "Channel 3 Count Register" },
+{ "CCR3", 0x1000114C, 0, 0xffffffff, 'x', "Channel 3 Control Register" },
+{ "RSSR3", 0x10001150, 0, 0xffffffff, 'x', "Channel 3 Request Source Select Register" },
+{ "BLR3", 0x10001154, 0, 0xffffffff, 'x', "Channel 3 Burst Length Register" },
+{ "RTOR3", 0x10001158, 0, 0xffffffff, 'x', "Channel 3 Request Time-Out Register" },
+{ "BUCR3", 0x10001158, 0, 0xffffffff, 'x', "Channel 3 Bus Utilization Control Register" },
+{ "CCNR3", 0x1000115C, 0, 0xffffffff, 'x', "Channel 3 Channel Counter Register" },
+{ "SAR4", 0x10001180, 0, 0xffffffff, 'x', "Channel 4 Source Address Register" },
+{ "DAR4", 0x10001184, 0, 0xffffffff, 'x', "Channel 4 Destination Address Register" },
+{ "CNTR4", 0x10001188, 0, 0xffffffff, 'x', "Channel 4 Count Register" },
+{ "CCR4", 0x1000118C, 0, 0xffffffff, 'x', "Channel 4 Control Register" },
+{ "RSSR4", 0x10001190, 0, 0xffffffff, 'x', "Channel 4 Request Source Select Register" },
+{ "BLR4", 0x10001194, 0, 0xffffffff, 'x', "Channel 4 Burst Length Register" },
+{ "RTOR4", 0x10001198, 0, 0xffffffff, 'x', "Channel 4 Request Time-Out Register" },
+{ "BUCR4", 0x10001198, 0, 0xffffffff, 'x', "Channel 4 Bus Utilization Control Register" },
+{ "CCNR", 0x1000119C, 0, 0xffffffff, 'x', "4 Channel 4 Channel Counter Register" },
+{ "SAR5", 0x100011C0, 0, 0xffffffff, 'x', "Channel 5 Source Address Register" },
+{ "DAR5", 0x100011C4, 0, 0xffffffff, 'x', "Channel 5 Destination Address Register" },
+{ "CNTR5", 0x100011C8, 0, 0xffffffff, 'x', "Channel 5 Count Register" },
+{ "CCR5", 0x100011CC, 0, 0xffffffff, 'x', "Channel 5 Control Register" },
+{ "RSSR5", 0x100011D0, 0, 0xffffffff, 'x', "Channel 5 Request Source Select Register" },
+{ "BLR5", 0x100011D4, 0, 0xffffffff, 'x', "Channel 5 Burst Length Register" },
+{ "RTOR5", 0x100011D8, 0, 0xffffffff, 'x', "Channel 5 Request Time-Out Register" },
+{ "BUCR5", 0x100011D8, 0, 0xffffffff, 'x', "Channel 5 Bus Utilization Control Register" },
+{ "CCNR5", 0x100011DC, 0, 0xffffffff, 'x', "Channel 5 Channel Counter Register" },
+{ "SAR6", 0x10001200, 0, 0xffffffff, 'x', "Channel 6 Source Address Register" },
+{ "DAR6", 0x10001204, 0, 0xffffffff, 'x', "Channel 6 Destination Address Register" },
+{ "CNTR6", 0x10001208, 0, 0xffffffff, 'x', "Channel 6 Count Register" },
+{ "CCR6", 0x1000120C, 0, 0xffffffff, 'x', "Channel 6 Control Register" },
+{ "RSSR6", 0x10001210, 0, 0xffffffff, 'x', "Channel 6 Request Source Select Register" },
+{ "BLR6", 0x10001214, 0, 0xffffffff, 'x', "Channel 6 Burst Length Register" },
+{ "RTOR6", 0x10001218, 0, 0xffffffff, 'x', "Channel 6 Request Time-Out Register" },
+{ "BUCR6", 0x10001218, 0, 0xffffffff, 'x', "Channel 6 Bus Utilization Control Register" },
+{ "CCNR6", 0x1000121C, 0, 0xffffffff, 'x', "Channel 6 Channel Counter Register" },
+{ "SAR7", 0x10001240, 0, 0xffffffff, 'x', "Channel 7 Source Address Register" },
+{ "DAR7", 0x10001244, 0, 0xffffffff, 'x', "Channel 7 Destination Address Register" },
+{ "CNTR7", 0x10001248, 0, 0xffffffff, 'x', "Channel 7 Count Register" },
+{ "CCR7", 0x1000124C, 0, 0xffffffff, 'x', "Channel 7 Control Register" },
+{ "RSSR7", 0x10001250, 0, 0xffffffff, 'x', "Channel 7 Request Source Select Register" },
+{ "BLR7", 0x10001254, 0, 0xffffffff, 'x', "Channel 7 Burst Length Register" },
+{ "RTOR7", 0x10001258, 0, 0xffffffff, 'x', "Channel 7 Request Time-Out Register" },
+{ "BUCR7", 0x10001258, 0, 0xffffffff, 'x', "Channel 7 Bus Utilization Control Register" },
+{ "CCNR7", 0x1000125C, 0, 0xffffffff, 'x', "Channel 7 Channel Counter Register" },
+{ "SAR8", 0x10001280, 0, 0xffffffff, 'x', "Channel 8 Source Address Register" },
+{ "DAR8", 0x10001284, 0, 0xffffffff, 'x', "Channel 8 Destination Address Register" },
+{ "CNTR8", 0x10001288, 0, 0xffffffff, 'x', "Channel 8 Count Register" },
+{ "CCR8", 0x1000128C, 0, 0xffffffff, 'x', "Channel 8 Control Register" },
+{ "RSSR8", 0x10001290, 0, 0xffffffff, 'x', "Channel 8 Request Source Select Register" },
+{ "BLR8", 0x10001294, 0, 0xffffffff, 'x', "Channel 8 Burst Length Register" },
+{ "RTOR8", 0x10001298, 0, 0xffffffff, 'x', "Channel 8 Request Time-Out Register" },
+{ "BUCR8", 0x10001298, 0, 0xffffffff, 'x', "Channel 8 Bus Utilization Control Register" },
+{ "CCNR8", 0x1000129C, 0, 0xffffffff, 'x', "Channel 8 Channel Counter Register" },
+{ "SAR9", 0x100012C0, 0, 0xffffffff, 'x', "Channel 9 Source Address Register" },
+{ "DAR9", 0x100012C4, 0, 0xffffffff, 'x', "Channel 9 Destination Address Register" },
+{ "CNTR9", 0x100012C8, 0, 0xffffffff, 'x', "Channel 9 Count Register" },
+{ "CCR9", 0x100012CC, 0, 0xffffffff, 'x', "Channel 9 Control Register" },
+{ "RSSR9", 0x100012D0, 0, 0xffffffff, 'x', "Channel 9 Request Source Select Register" },
+{ "BLR9", 0x100012D4, 0, 0xffffffff, 'x', "Channel 9 Burst Length Register" },
+{ "RTOR9", 0x100012D8, 0, 0xffffffff, 'x', "Channel 9 Request Time-Out Register" },
+{ "BUCR9", 0x100012D8, 0, 0xffffffff, 'x', "Channel 9 Bus Utilization Control Register" },
+{ "CCNR9", 0x100012DC, 0, 0xffffffff, 'x', "Channel 9 Channel Counter Register" },
+{ "SAR10", 0x10001300, 0, 0xffffffff, 'x', "Channel 10 Source Address Register" },
+{ "DAR10", 0x10001304, 0, 0xffffffff, 'x', "Channel 10 Destination Address Register" },
+{ "CNTR10", 0x10001308, 0, 0xffffffff, 'x', "Channel 10 Count Register" },
+{ "CCR10", 0x1000130C, 0, 0xffffffff, 'x', "Channel 10 Control Register" },
+{ "RSSR10", 0x10001310, 0, 0xffffffff, 'x', "Channel 10 Request Source Select Register" },
+{ "BLR10", 0x10001314, 0, 0xffffffff, 'x', "Channel 10 Burst Length Register" },
+{ "RTOR10", 0x10001318, 0, 0xffffffff, 'x', "Channel 10 Request Time-Out Register" },
+{ "BUCR10", 0x10001318, 0, 0xffffffff, 'x', "Channel 10 Bus Utilization Control Register" },
+{ "CCNR10", 0x1000131C, 0, 0xffffffff, 'x', "Channel 10 Channel Counter Register" },
+{ "SAR11", 0x10001340, 0, 0xffffffff, 'x', "Channel 11 Source Address Register" },
+{ "DAR11", 0x10001344, 0, 0xffffffff, 'x', "Channel 11 Destination Address Register" },
+{ "CNTR11", 0x10001348, 0, 0xffffffff, 'x', "Channel 11 Count Register" },
+{ "CCR11", 0x1000134C, 0, 0xffffffff, 'x', "Channel 11 Control Register" },
+{ "RSSR11", 0x10001350, 0, 0xffffffff, 'x', "Channel 11 Request Source Select Register" },
+{ "BLR11", 0x10001354, 0, 0xffffffff, 'x', "Channel 11 Burst Length Register" },
+{ "RTOR11", 0x10001358, 0, 0xffffffff, 'x', "Channel 11 Request Time-Out Register" },
+{ "BUCR11", 0x10001358, 0, 0xffffffff, 'x', "Channel 11 Bus Utilization Control Register" },
+{ "CCNR11", 0x1000135C, 0, 0xffffffff, 'x', "Channel 11 Channel Counter Register" },
+{ "SAR12", 0x10001380, 0, 0xffffffff, 'x', "Channel 12 Source Address Register" },
+{ "DAR12", 0x10001384, 0, 0xffffffff, 'x', "Channel 12 Destination Address Register" },
+{ "CNTR12", 0x10001388, 0, 0xffffffff, 'x', "Channel 12 Count Register" },
+{ "CCR12", 0x1000138C, 0, 0xffffffff, 'x', "Channel 12 Control Register" },
+{ "RSSR12", 0x10001390, 0, 0xffffffff, 'x', "Channel 12 Request Source Select Register" },
+{ "BLR12", 0x10001394, 0, 0xffffffff, 'x', "Channel 12 Burst Length Register" },
+{ "RTOR12", 0x10001398, 0, 0xffffffff, 'x', "Channel 12 Request Time-Out Register" },
+{ "BUCR12", 0x10001398, 0, 0xffffffff, 'x', "Channel 12 Bus Utilization Control Register" },
+{ "CCNR12", 0x1000139C, 0, 0xffffffff, 'x', "Channel 14 Channel Counter Register" },
+{ "SAR13", 0x100013C0, 0, 0xffffffff, 'x', "Channel 13 Source Address Register" },
+{ "DAR13", 0x100013C4, 0, 0xffffffff, 'x', "Channel 13 Destination Address Register" },
+{ "CNTR13", 0x100013C8, 0, 0xffffffff, 'x', "Channel 13 Count Register" },
+{ "CCR13", 0x100013CC, 0, 0xffffffff, 'x', "Channel 13 Control Register" },
+{ "RSSR13", 0x100013D0, 0, 0xffffffff, 'x', "Channel 13 Request Source Select Register" },
+{ "BLR13", 0x100013D4, 0, 0xffffffff, 'x', "Channel 13 Burst Length Register" },
+{ "RTOR13", 0x100013D8, 0, 0xffffffff, 'x', "Channel 13 Request Time-Out Register" },
+{ "BUCR13", 0x100013D8, 0, 0xffffffff, 'x', "Channel 13 Bus Utilization Control Register" },
+{ "CCNR13", 0x100013DC, 0, 0xffffffff, 'x', "Channel 13 Channel Counter Register" },
+{ "SAR14", 0x10001400, 0, 0xffffffff, 'x', "Channel 14 Source Address Register" },
+{ "DAR14", 0x10001404, 0, 0xffffffff, 'x', "Channel 14 Destination Address Register" },
+{ "CNTR14", 0x10001408, 0, 0xffffffff, 'x', "Channel 14 Count Register" },
+{ "CCR14", 0x1000140C, 0, 0xffffffff, 'x', "Channel 14 Control Register" },
+{ "RSSR14", 0x10001410, 0, 0xffffffff, 'x', "Channel 14 Request Source Select Register" },
+{ "BLR14", 0x10001414, 0, 0xffffffff, 'x', "Channel 14 Burst Length Register" },
+{ "RTOR14", 0x10001418, 0, 0xffffffff, 'x', "Channel 14 Request Time-Out Register" },
+{ "BUCR14", 0x10001418, 0, 0xffffffff, 'x', "Channel 14 Bus Utilization Control Register" },
+{ "CCNR14", 0x1000141C, 0, 0xffffffff, 'x', "Channel 14 Channel Counter Register" },
+{ "SAR15", 0x10001440, 0, 0xffffffff, 'x', "Channel 15 Source Address Register" },
+{ "DAR15", 0x10001444, 0, 0xffffffff, 'x', "Channel 15 Destination Address Register" },
+{ "CNTR15", 0x10001448, 0, 0xffffffff, 'x', "Channel 15 Count Register" },
+{ "CCR15", 0x1000144C, 0, 0xffffffff, 'x', "Channel 15 Control Register" },
+{ "RSSR15", 0x10001450, 0, 0xffffffff, 'x', "Channel 15 Request Source Select Register" },
+{ "BLR15", 0x10001454, 0, 0xffffffff, 'x', "Channel 15 Burst Length Register" },
+{ "RTOR15", 0x10001458, 0, 0xffffffff, 'x', "Channel 15 Request Time-Out Register" },
+{ "BUCR15", 0x10001458, 0, 0xffffffff, 'x', "Channel 15 Bus Utilization Control Register" },
+{ "CCNR15", 0x1000145C, 0, 0xffffffff, 'x', "Channel 15 Channel Counter Register" },
+{ "TCR", 0x10001480, 0, 0xffffffff, 'x', "Test Control Register" },
+{ "TFIFOAR", 0x10001484, 0, 0xffffffff, 'x', "Test FIFO A Register" },
+{ "TDIPR", 0x1000148C, 0, 0xffffffff, 'x', "Test DMA In Progress Register" },
+{ "TFIFOBR", 0x10001490, 0, 0xffffffff, 'x', "Test FIFO B Register" },
+{ "TDRR_L", 0x10001498, 0, 0xffffffff, 'x', "Low 32 DMA Request Register" },
+{ "TDRR_H", 0x1000149C, 0, 0xffffffff, 'x', "High 32 DMA Request Register" },
+// WDOG
+{ "WCR", 0x10002000, 0, 0xffffffff, 'x', "Watchdog Control Register" },
+{ "WSR", 0x10002002, 0, 0xffffffff, 'x', "Watchdog Service Register" },
+{ "WRSR", 0x10002004, 0, 0xffffffff, 'x', "Watchdog Reset Status Register" },
+// GPT1
+{ "TCTL1", 0x10003000, 0, 0xffffffff, 'x', "GPT Control Register 1" },
+{ "TPRER1", 0x10003004, 0, 0xffffffff, 'x', "GPT Prescaler Register 1" },
+{ "TCMP1", 0x10003008, 0, 0xffffffff, 'x', "GPT Compare Register 1" },
+{ "TCR1", 0x1000300C, 0, 0xffffffff, 'x', "GPT Capture Register 1" },
+{ "TCN1", 0x10003010, 0, 0xffffffff, 'x', "GPT Counter Register 1" },
+{ "TSTAT1", 0x10003014, 0, 0xffffffff, 'x', "GPT Status Register 1" },
+// GPT2
+{ "TCTL2", 0x10004000, 0, 0xffffffff, 'x', "GPT Control Register 2" },
+{ "TPRER2", 0x10004004, 0, 0xffffffff, 'x', "GPT Prescaler Register 2" },
+{ "TCMP2", 0x10004008, 0, 0xffffffff, 'x', "GPT Compare Register 2" },
+{ "TCR2", 0x1000400C, 0, 0xffffffff, 'x', "GPT Capture Register 2" },
+{ "TCN2", 0x10004010, 0, 0xffffffff, 'x', "GPT Counter Register 2" },
+{ "TSTAT2", 0x10004014, 0, 0xffffffff, 'x', "GPT Status Register 2" },
+// GPT3
+{ "TCTL3", 0x10005000, 0, 0xffffffff, 'x', "GPT Control Register 3" },
+{ "TPRER3", 0x10005004, 0, 0xffffffff, 'x', "GPT Prescaler Register 3" },
+{ "TCMP3", 0x10005008, 0, 0xffffffff, 'x', "GPT Compare Register 3" },
+{ "TCR3", 0x1000500C, 0, 0xffffffff, 'x', "GPT Capture Register 3" },
+{ "TCN3", 0x10005010, 0, 0xffffffff, 'x', "GPT Counter Register 3" },
+{ "TSTAT3", 0x10005014, 0, 0xffffffff, 'x', "GPT Status Register 3" },
+// PWM
+{ "PWMCR", 0x10006000, 0, 0xffffffff, 'x', "PWM Control Register" },
+{ "PWMSR", 0x10006004, 0, 0xffffffff, 'x', "PWM Status Register" },
+{ "PWMIR", 0x10006008, 0, 0xffffffff, 'x', "PWM Interrupt Register" },
+{ "PWMSAR", 0x1000600C, 0, 0xffffffff, 'x', "PWM Sample Register" },
+{ "PWMPR", 0x10006010, 0, 0xffffffff, 'x', "PWM Period Register" },
+{ "PWMCNR", 0x10006014, 0, 0xffffffff, 'x', "PWM Counter Register" },
+// RTC
+{ "HOURMIN", 0x10007000, 0, 0xffffffff, 'x', "RTC Hours and Minutes Counter Register" },
+{ "SECONDS", 0x10007004, 0, 0xffffffff, 'x', "RTC Seconds Counter Register" },
+{ "ALRM_HM", 0x10007008, 0, 0xffffffff, 'x', "RTC Hours and Minutes Alarm Register" },
+{ "ALRM_SEC", 0x1000700C, 0, 0xffffffff, 'x', "RTC Seconds Alarm Register" },
+{ "RCCTL", 0x10007010, 0, 0xffffffff, 'x', "RTC Control Register" },
+{ "RTCISR", 0x10007014, 0, 0xffffffff, 'x', "RTC Interrupt Status Register" },
+{ "RTCIENR", 0x10007018, 0, 0xffffffff, 'x', "RTC Interrupt Enable Register" },
+{ "STPWCH", 0x1000701C, 0, 0xffffffff, 'x', "Stopwatch Minutes Register" },
+{ "DAYR", 0x10007020, 0, 0xffffffff, 'x', "RTC Days Counter Register" },
+{ "DAYALARM", 0x10007024, 0, 0xffffffff, 'x', "RTC Day Alarm Register" },
+// KPP
+{ "KPCR", 0x10008000, 0, 0xffffffff, 'x', "Keypad Control Register" },
+{ "KPSR", 0x10008002, 0, 0xffffffff, 'x', "Keypad Status Register" },
+{ "KDDR", 0x10008004, 0, 0xffffffff, 'x', "Keypad Data Direction Register" },
+{ "KPDR", 0x10008006, 0, 0xffffffff, 'x', "Keypad Data Register" },
+// O-Wire
+{ "CONTROL", 0x10009000, 0, 0xffffffff, 'x', "1-Wire Control Register" },
+{ "TIME_DIVIDER", 0x10009002, 0, 0xffffffff, 'x', "1-Wire Time Divider Register" },
+{ "RESET", 0x10009004, 0, 0xffffffff, 'x', "1-Wire Reset Register" },
+// UART1
+{ "UXRD_1", 0x1000A000, 0, 0xffffffff, 'x', "UART1 Receiver Register" },
+{ "UTXD_1", 0x1000A040, 0, 0xffffffff, 'x', "UART1 Transmitter Register" },
+{ "UCR1_1", 0x1000A080, 0, 0xffffffff, 'x', "UART1 Control Register" },
+{ "UCR2_1", 0x1000A084, 0, 0xffffffff, 'x', "UART1 Control Register 2" },
+{ "UCR3_1", 0x1000A088, 0, 0xffffffff, 'x', "UART1 Control Register 3" },
+{ "UCR4_1", 0x1000A08C, 0, 0xffffffff, 'x', "UART1 Control Register 4" },
+{ "UFCR_1", 0x1000A090, 0, 0xffffffff, 'x', "UART1 FIFO Control Register" },
+{ "USR1_1", 0x1000A094, 0, 0xffffffff, 'x', "UART1 Status Register 1" },
+{ "USR2_1", 0x1000A098, 0, 0xffffffff, 'x', "UART1 Status Register 2" },
+{ "UESC_1", 0x1000A09C, 0, 0xffffffff, 'x', "UART1 Escape Character Register" },
+{ "UTIM_1", 0x1000A0A0, 0, 0xffffffff, 'x', "UART1 Escape Timer Register" },
+{ "UBIR_1", 0x1000A0A4, 0, 0xffffffff, 'x', "UART1 BRM Incremental Register" },
+{ "UBMR_1", 0x1000A0A8, 0, 0xffffffff, 'x', "UART1 BRM Modulator Register" },
+{ "UBRC_1", 0x1000A0AC, 0, 0xffffffff, 'x', "UART1 Baud Rate Count Register" },
+{ "ONEMS_1", 0x1000A0B0, 0, 0xffffffff, 'x', "UART1 One Millisecond Register" },
+{ "UTS_1", 0x1000A0B4, 0, 0xffffffff, 'x', "UART1 Test Register 1" },
+// UART2
+{ "UXRD_2", 0x1000B000, 0, 0xffffffff, 'x', "UART2 Receiver Register" },
+{ "UTXD_2", 0x1000B040, 0, 0xffffffff, 'x', "UART2 Transmitter Register" },
+{ "UCR1_2", 0x1000B080, 0, 0xffffffff, 'x', "UART2 Control Register" },
+{ "UCR2_2", 0x1000B084, 0, 0xffffffff, 'x', "UART2 Control Register 2" },
+{ "UCR3_2", 0x1000B088, 0, 0xffffffff, 'x', "UART2 Control Register 3" },
+{ "UCR4_2", 0x1000B08C, 0, 0xffffffff, 'x', "UART2 Control Register 4" },
+{ "UFCR_2", 0x1000B090, 0, 0xffffffff, 'x', "UART2 FIFO Control Register" },
+{ "USR1_2", 0x1000B094, 0, 0xffffffff, 'x', "UART2 Status Register 1" },
+{ "USR2_2", 0x1000B098, 0, 0xffffffff, 'x', "UART2 Status Register 2" },
+{ "UESC_2", 0x1000B09C, 0, 0xffffffff, 'x', "UART2 Escape Character Register" },
+{ "UTIM_2", 0x1000B0A0, 0, 0xffffffff, 'x', "UART2 Escape Timer Register" },
+{ "UBIR_2", 0x1000B0A4, 0, 0xffffffff, 'x', "UART2 BRM Incremental Register" },
+{ "UBMR_2", 0x1000B0A8, 0, 0xffffffff, 'x', "UART2 BRM Modulator Register" },
+{ "UBRC_2", 0x1000B0AC, 0, 0xffffffff, 'x', "UART2 Baud Rate Count Register" },
+{ "ONEMS_2", 0x1000B0B0, 0, 0xffffffff, 'x', "UART2 One Millisecond Register" },
+{ "UTS_2", 0x1000B0B4, 0, 0xffffffff, 'x', "UART2 Test Register 1" },
+// UART3
+{ "UXRD_3", 0x1000C000, 0, 0xffffffff, 'x', "UART3 Receiver Register" },
+{ "UTXD_3", 0x1000C040, 0, 0xffffffff, 'x', "UART3 Transmitter Register" },
+{ "UCR1_3", 0x1000C080, 0, 0xffffffff, 'x', "UART3 Control Register" },
+{ "UCR2_3", 0x1000C084, 0, 0xffffffff, 'x', "UART3 Control Register 2" },
+{ "UCR3_3", 0x1000C088, 0, 0xffffffff, 'x', "UART3 Control Register 3" },
+{ "UCR4_3", 0x1000C08C, 0, 0xffffffff, 'x', "UART3 Control Register 4" },
+{ "UFCR_3", 0x1000C090, 0, 0xffffffff, 'x', "UART3 FIFO Control Register" },
+{ "USR1_3", 0x1000C094, 0, 0xffffffff, 'x', "UART3 Status Register 1" },
+{ "USR2_3", 0x1000C098, 0, 0xffffffff, 'x', "UART3 Status Register 2" },
+{ "UESC_3", 0x1000C09C, 0, 0xffffffff, 'x', "UART3 Escape Character Register" },
+{ "UTIM_3", 0x1000C0A0, 0, 0xffffffff, 'x', "UART3 Escape Timer Register" },
+{ "UBIR_3", 0x1000C0A4, 0, 0xffffffff, 'x', "UART3 BRM Incremental Register" },
+{ "UBMR_3", 0x1000C0A8, 0, 0xffffffff, 'x', "UART3 BRM Modulator Register" },
+{ "UBRC_3", 0x1000C0AC, 0, 0xffffffff, 'x', "UART3 Baud Rate Count Register" },
+{ "ONEMS_3", 0x1000C0B0, 0, 0xffffffff, 'x', "UART3 One Millisecond Register" },
+{ "UTS_3", 0x1000C0B4, 0, 0xffffffff, 'x', "UART3 Test Register 1" },
+// UART4
+{ "UXRD_4", 0x1000D000, 0, 0xffffffff, 'x', "UART4 Receiver Register" },
+{ "UTXD_4", 0x1000D040, 0, 0xffffffff, 'x', "UART4 Transmitter Register" },
+{ "UCR1_4", 0x1000D080, 0, 0xffffffff, 'x', "UART4 Control Register" },
+{ "UCR2_4", 0x1000D084, 0, 0xffffffff, 'x', "UART4 Control Register 2" },
+{ "UCR3_4", 0x1000D088, 0, 0xffffffff, 'x', "UART4 Control Register 3" },
+{ "UCR4_4", 0x1000D08C, 0, 0xffffffff, 'x', "UART4 Control Register 4" },
+{ "UFCR_4", 0x1000D090, 0, 0xffffffff, 'x', "UART4 FIFO Control Register" },
+{ "USR1_4", 0x1000D094, 0, 0xffffffff, 'x', "UART4 Status Register 1" },
+{ "USR2_4", 0x1000D098, 0, 0xffffffff, 'x', "UART4 Status Register 2" },
+{ "UESC_4", 0x1000D09C, 0, 0xffffffff, 'x', "UART4 Escape Character Register" },
+{ "UTIM_4", 0x1000D0A0, 0, 0xffffffff, 'x', "UART4 Escape Timer Register" },
+{ "UBIR_4", 0x1000D0A4, 0, 0xffffffff, 'x', "UART4 BRM Incremental Register" },
+{ "UBMR_4", 0x1000D0A8, 0, 0xffffffff, 'x', "UART4 BRM Modulator Register" },
+{ "UBRC_4", 0x1000D0AC, 0, 0xffffffff, 'x', "UART4 Baud Rate Count Register" },
+{ "ONEMS_4", 0x1000D0B0, 0, 0xffffffff, 'x', "UART4 One Millisecond Register" },
+{ "UTS_4", 0x1000D0B4, 0, 0xffffffff, 'x', "UART4 Test Register 1" },
+// CSPI1
+{ "RXDATA1", 0x1000E000, 0, 0xffffffff, 'x', "Receive Data Register 1" },
+{ "TXDATA1", 0x1000E004, 0, 0xffffffff, 'x', "Transmit Data Register 1" },
+{ "CONTROL_REG1", 0x1000E008, 0, 0xffffffff, 'x', "CSPI Control Register 1" },
+{ "INT_REG1", 0x1000E00C, 0, 0xffffffff, 'x', "Interrupt Control/Status Register 1" },
+{ "TEST_REG", 0x1000E010, 0, 0xffffffff, 'x', "CSPI Test Register 1" },
+{ "PERIOD1", 0x1000E014, 0, 0xffffffff, 'x', "CSPI Sample Period Control Register 1" },
+{ "CSPI_DMA1", 0x1000E018, 0, 0xffffffff, 'x', "CSPI DMA Register 1" },
+{ "CSPI_RESET1", 0x1000E01C, 0, 0xffffffff, 'x', "CSPI 1 Soft Reset Register" },
+// CSPI2
+{ "RXDATA2", 0x1000F000, 0, 0xffffffff, 'x', "Receive Data Register 2" },
+{ "TXDATA2", 0x1000F004, 0, 0xffffffff, 'x', "Transmit Data Register 2" },
+{ "CONTROL_REG2", 0x1000F008, 0, 0xffffffff, 'x', "CSPI Control Register 2" },
+{ "INT_REG2", 0x1000F00C, 0, 0xffffffff, 'x', "Interrupt Control/Status Register 2" },
+{ "TEST_REG", 0x1000F010, 0, 0xffffffff, 'x', "2 CSPI Test Register 2" },
+{ "PERIOD2", 0x1000F014, 0, 0xffffffff, 'x', "CSPI Sample Period Control Register 2" },
+{ "CSPI_DMA2", 0x1000F018, 0, 0xffffffff, 'x', "CSPI DMA Register 2" },
+{ "CSPI_RESET2", 0x1000F01C, 0, 0xffffffff, 'x', "CSPI 2 Soft Reset Register" },
+// SSI1
+{ "STX0", 0x10010000, 0, 0xffffffff, 'x', "SSI Transmit Data Register 0" },
+{ "STX1", 0x10010004, 0, 0xffffffff, 'x', "SSI Transmit Data Register 1" },
+{ "SRX0", 0x10010008, 0, 0xffffffff, 'x', "SSI Receive Data Register 0" },
+{ "SRX1", 0x1001000C, 0, 0xffffffff, 'x', "SSI Receive Data Register 1" },
+{ "SCR", 0x10010010, 0, 0xffffffff, 'x', "SSI Control Register" },
+{ "SISR", 0x10010014, 0, 0xffffffff, 'x', "SSI Interrupt Status Register" },
+{ "SIER", 0x10010018, 0, 0xffffffff, 'x', "SSI Interrupt Enable Register" },
+{ "STCR", 0x1001001C, 0, 0xffffffff, 'x', "SSI Transmit Configuration Register" },
+{ "SRCR", 0x10010020, 0, 0xffffffff, 'x', "SSI Receive Configuration Register" },
+{ "STCCR", 0x10010024, 0, 0xffffffff, 'x', "SSI Transmit Clock Control Register" },
+{ "SRCCR", 0x10010028, 0, 0xffffffff, 'x', "SSI Receive Clock Control Register" },
+{ "SFCSR", 0x1001002C, 0, 0xffffffff, 'x', "SSI FIFO Control/Status Register" },
+{ "STR", 0x10010030, 0, 0xffffffff, 'x', "SSI Test Register" },
+{ "SOR", 0x10010034, 0, 0xffffffff, 'x', "SSI Option Register" },
+{ "SACNT", 0x10010038, 0, 0xffffffff, 'x', "SSI AC97 Control Register" },
+{ "SACADD", 0x1001003C, 0, 0xffffffff, 'x', "SSI AC97 Command Address Register" },
+{ "SACDAT", 0x10010040, 0, 0xffffffff, 'x', "SSI AC97 Command Data Register" },
+{ "SATAG", 0x10010044, 0, 0xffffffff, 'x', "SSI AC97 Tag Register" },
+{ "STMSK", 0x10010048, 0, 0xffffffff, 'x', "SSI Transmit Time Slot Mask Register" },
+{ "SRMSK", 0x1001004C, 0, 0xffffffff, 'x', "SSI Receive Time Slot Mask Register" },
+{ "SACCST", 0x10010050, 0, 0xffffffff, 'x', "SSI AC97 Channel Status Register" },
+{ "SACCEN", 0x10010054, 0, 0xffffffff, 'x', "SSI AC97 Channel Enable Register" },
+{ "SACCDIS", 0x10010058, 0, 0xffffffff, 'x', "SSI AC97 Channel Disable Register" },
+// SSI2
+{ "STX0", 0x10011000, 0, 0xffffffff, 'x', "SSI Transmit Data Register 0" },
+{ "STX1", 0x10011004, 0, 0xffffffff, 'x', "SSI Transmit Data Register 1" },
+{ "SRX0", 0x10011008, 0, 0xffffffff, 'x', "SSI Receive Data Register 0" },
+{ "SRX1", 0x1001100C, 0, 0xffffffff, 'x', "SSI Receive Data Register 1" },
+{ "SCR", 0x10011010, 0, 0xffffffff, 'x', "SSI Control Register" },
+{ "SISR", 0x10011014, 0, 0xffffffff, 'x', "SSI Interrupt Status Register" },
+{ "SIER", 0x10011018, 0, 0xffffffff, 'x', "SSI Interrupt Enable Register" },
+{ "STCR", 0x1001101C, 0, 0xffffffff, 'x', "SSI Transmit Configuration Register" },
+{ "SRCR", 0x10011020, 0, 0xffffffff, 'x', "SSI Receive Configuration Register" },
+{ "STCCR", 0x10011024, 0, 0xffffffff, 'x', "SSI Transmit Clock Control Register" },
+{ "SRCCR", 0x10011028, 0, 0xffffffff, 'x', "SSI Receive Clock Control Register" },
+{ "SFCSR", 0x1001102C, 0, 0xffffffff, 'x', "SSI FIFO Control/Status Register" },
+{ "STR", 0x10011030, 0, 0xffffffff, 'x', "SSI Test Register" },
+{ "SOR", 0x10011034, 0, 0xffffffff, 'x', "SSI Option Register" },
+{ "SACNT", 0x10011038, 0, 0xffffffff, 'x', "SSI AC97 Control Register" },
+{ "SACADD", 0x1001103C, 0, 0xffffffff, 'x', "SSI AC97 Command Address Register" },
+{ "SACDAT", 0x10011040, 0, 0xffffffff, 'x', "SSI AC97 Command Data Register" },
+{ "SATAG", 0x10011044, 0, 0xffffffff, 'x', "SSI AC97 Tag Register" },
+{ "STMSK", 0x10011048, 0, 0xffffffff, 'x', "SSI Transmit Time Slot Mask Register" },
+{ "SRMSK", 0x1001104C, 0, 0xffffffff, 'x', "SSI Receive Time Slot Mask Register" },
+{ "SACCST", 0x10011050, 0, 0xffffffff, 'x', "SSI AC97 Channel Status Register" },
+{ "SACCEN", 0x10011054, 0, 0xffffffff, 'x', "SSI AC97 Channel Enable Register" },
+{ "SACCDIS", 0x10011058, 0, 0xffffffff, 'x', "SSI AC97 Channel Disable Register" },
+// I2C1
+{ "IADR", 0x10012000, 0, 0xffffffff, 'x', "I2C Address Register" },
+{ "IFDR", 0x10012004, 0, 0xffffffff, 'x', "I2C Frequency Divider Register" },
+{ "I2CR", 0x10012008, 0, 0xffffffff, 'x', "I2C Control Register" },
+{ "I2SR", 0x1001200C, 0, 0xffffffff, 'x', "I2C Status Register" },
+{ "I2DR", 0x10012010, 0, 0xffffffff, 'x', "I2C Data I/O Register" },
+// SDHC1
+{ "STR_STP_CLK", 0x10013000, 0, 0xffffffff, 'x', "MMC/SD1 Clock Control Register" },
+{ "STATUS", 0x10013004, 0, 0xffffffff, 'x', "(Read Only) MMC/SD1 Status Register" },
+{ "CLK_RATE", 0x10013008, 0, 0xffffffff, 'x', "MMC/SD1 Clock Rate Register" },
+{ "CMD_DAT_CONT", 0x1001300C, 0, 0xffffffff, 'x', "MMC/SD1 Command and Data Control Register" },
+{ "RESPONSE_TO", 0x10013010, 0, 0xffffffff, 'x', "MMC/SD1 Response Time Out Register" },
+{ "READ_TO", 0x10013014, 0, 0xffffffff, 'x', "MMC/SD1 Read Time Out Register" },
+{ "BLK_LEN", 0x10013018, 0, 0xffffffff, 'x', "MMC/SD1 Block Length Register" },
+{ "NOB", 0x1001301C, 0, 0xffffffff, 'x', "MMC/SD1 Number of Block Register" },
+{ "REV_NO", 0x10013020, 0, 0xffffffff, 'x', "MMC/SD1 Revision Number Register" },
+{ "INT_CNTL", 0x10013024, 0, 0xffffffff, 'x', "MMC/SD1 Interrupt Control Register" },
+{ "CMD", 0x10013028, 0, 0xffffffff, 'x', "MMC/SD1 Command Number Register" },
+{ "ARGH", 0x1001302C, 0, 0xffffffff, 'x', "MMC/SD1 Higher Argument Register" },
+{ "ARGL", 0x10013030, 0, 0xffffffff, 'x', "MMC/SD1 Lower Argument Register" },
+{ "RES_FIFO", 0x10013034, 0, 0xffffffff, 'x', "(Read Only) MMC/SD1 Response FIFO Register" },
+{ "BUFFER_ACCESS", 0x10013038, 0, 0xffffffff, 'x', "MMC/SD1 Buffer Access Register" },
+// SDHC2
+{ "STR_STP_CLK", 0x10014000, 0, 0xffffffff, 'x', "MMC/SD2 Clock Control Register" },
+{ "STATUS", 0x10014004, 0, 0xffffffff, 'x', "(Read Only) MMC/SD2 Status Register" },
+{ "CLK_RATE", 0x10014008, 0, 0xffffffff, 'x', "MMC/SD2 Clock Rate Register" },
+{ "CMD_DAT_CONT", 0x1001400C, 0, 0xffffffff, 'x', "MMC/SD2 Command and Data Control Register" },
+{ "RESPONSE_TO", 0x10014010, 0, 0xffffffff, 'x', "MMC/SD2 Response Time Out Register" },
+{ "READ_TO", 0x10014014, 0, 0xffffffff, 'x', "MMC/SD2 Read Time Out Register" },
+{ "BLK_LEN", 0x10014018, 0, 0xffffffff, 'x', "MMC/SD2 Block Length Register" },
+{ "NOB", 0x1001401C, 0, 0xffffffff, 'x', "MMC/SD2 Number of Block Register" },
+{ "REV_NO", 0x10014020, 0, 0xffffffff, 'x', "MMC/SD2 Revision Number Register" },
+{ "INT_CNTL", 0x10014024, 0, 0xffffffff, 'x', "MMC/SD2 Interrupt Control Register" },
+{ "CMD", 0x10014028, 0, 0xffffffff, 'x', "MMC/SD2 Command Number Register" },
+{ "ARGH", 0x1001402C, 0, 0xffffffff, 'x', "MMC/SD2 Higher Argument Register" },
+{ "ARGL", 0x10014030, 0, 0xffffffff, 'x', "MMC/SD2 Lower Argument Register" },
+{ "RES_FIFO", 0x10014034, 0, 0xffffffff, 'x', "(Read Only) MMC/SD2 Response FIFO Register" },
+{ "BUFFER_ACCESS", 0x10014038, 0, 0xffffffff, 'x', "MMC/SD2 Buffer Access Register" },
+// GPIO
+{ "PTA_DDIR", 0x10015000, 0, 0xffffffff, 'x', "Data Direction Register, Port A" },
+{ "PTA_OCR1", 0x10015004, 0, 0xffffffff, 'x', "Output Configuration Register 1 (OCR1), Port" },
+{ "PTA_OCR2", 0x10015008, 0, 0xffffffff, 'x', "Output Configuration Register 2 (OCR2), Port" },
+{ "PTA_ICONFA1", 0x1001500C, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA1), Port" },
+{ "PTA_ICONFA2", 0x10015010, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA2), Port" },
+{ "PTA_ICONFB1", 0x10015014, 0, 0xffffffff, 'x', "Input Configuration Register B1 (ICONFB1), Port" },
+{ "PTA_ICONFB2", 0x10015018, 0, 0xffffffff, 'x', "Input Configuration Register B2 (ICONFB2), Port" },
+{ "PTA_DR", 0x1001501c, 0, 0xffffffff, 'x', "Data Register, Port A" },
+{ "PTA_GIUS", 0x10015020, 0, 0xffffffff, 'x', "GPIO In Use Register, Port A" },
+{ "PTA_SSR", 0x10015024, 0, 0xffffffff, 'x', "Sample Status Register, Port A" },
+{ "PTA_ICR1", 0x10015028, 0, 0xffffffff, 'x', "Interrupt Configuration Register 1, Port A" },
+{ "PTA_ICR2", 0x1001502C, 0, 0xffffffff, 'x', "Interrupt Configuration Register 2, Port A" },
+{ "PTA_IMR", 0x10015030, 0, 0xffffffff, 'x', "Interrupt Mask Register, Port A" },
+{ "PTA_ISR", 0x10015034, 0, 0xffffffff, 'x', "Interrupt Status Register, Port A" },
+{ "PTA_GPR", 0x10015038, 0, 0xffffffff, 'x', "General Purpose Register, Port A" },
+{ "PTA_SWR", 0x1001503c, 0, 0xffffffff, 'x', "Software Reset Register, Port A" },
+{ "PTA_PUEN", 0x10015040, 0, 0xffffffff, 'x', "Pull_up Enable Register, Port A" },
+{ "PTB_DDIR", 0x10015100, 0, 0xffffffff, 'x', "Data Direction Register, Port B" },
+{ "PTB_OCR1", 0x10015104, 0, 0xffffffff, 'x', "Output Configuration Register 1 (OCR1), Port" },
+{ "PTB_OCR2", 0x10015108, 0, 0xffffffff, 'x', "Output Configuration Register 2 (OCR2), Port" },
+{ "PTB_ICONFA1", 0x1001510c, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA1), Port" },
+{ "PTB_ICONFA2", 0x10015110, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA2), Port" },
+{ "PTB_ICONFB1", 0x10015114, 0, 0xffffffff, 'x', "Input Configuration Register B1 (ICONFB1), Port" },
+{ "PTB_ICONFB2", 0x10015118, 0, 0xffffffff, 'x', "Input Configuration Register B2 (ICONFB2), Port" },
+{ "PTB_DR", 0x1001511c, 0, 0xffffffff, 'x', "Data Register, Port B" },
+{ "PTB_GIUS", 0x10015120, 0, 0xffffffff, 'x', "GPIO In Use Register, Port B" },
+{ "PTB_SSR", 0x10015124, 0, 0xffffffff, 'x', "Sample Status Register, Port B" },
+{ "PTB_ICR1", 0x10015128, 0, 0xffffffff, 'x', "Interrupt Configuration Register 1, Port B" },
+{ "PTB_ICR2", 0x1001512C, 0, 0xffffffff, 'x', "Interrupt Configuration Register 2, Port B" },
+{ "PTB_IMR", 0x10015130, 0, 0xffffffff, 'x', "Interrupt Mask Register, Port B" },
+{ "PTB_ISR", 0x10015134, 0, 0xffffffff, 'x', "Interrupt Status Register, Port B" },
+{ "PTB_GPR", 0x10015138, 0, 0xffffffff, 'x', "General Purpose Register, Port B" },
+{ "PTB_SWR", 0x1001513c, 0, 0xffffffff, 'x', "Software Reset Register, Port B" },
+{ "PTB_PUEN", 0x10015140, 0, 0xffffffff, 'x', "Pull_up Enable Register, Port B" },
+{ "PTC_DDIR", 0x10015200, 0, 0xffffffff, 'x', "Data Direction Register, Port C" },
+{ "PTC_OCR1", 0x10015204, 0, 0xffffffff, 'x', "Output Configuration Register 1 (OCR1), Port" },
+{ "PTC_OCR2", 0x10015208, 0, 0xffffffff, 'x', "Output Configuration Register 2 (OCR2), Port" },
+{ "PTC_ICONFA1", 0x1001520c, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA1), Port" },
+{ "PTC_ICONFA2", 0x10015210, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA2), Port" },
+{ "PTC_ICONFB1", 0x10015214, 0, 0xffffffff, 'x', "Input Configuration Register B1 (ICONFB1), Port" },
+{ "PTC_ICONFB2", 0x10015218, 0, 0xffffffff, 'x', "Input Configuration Register B2 (ICONFB2), Port" },
+{ "PTC_DR", 0x1001521C, 0, 0xffffffff, 'x', "Data Register, Port C" },
+{ "PTC_GIUS", 0x10015220, 0, 0xffffffff, 'x', "GPIO In Use Register, Port C" },
+{ "PTC_SSR", 0x10015224, 0, 0xffffffff, 'x', "Sample Status Register, Port C" },
+{ "PTC_ICR1", 0x10015228, 0, 0xffffffff, 'x', "Interrupt Configuration Register 1, Port C" },
+{ "PTC_ICR2", 0x1001522C, 0, 0xffffffff, 'x', "Interrupt Configuration Register 2, Port C" },
+{ "PTC_IMR", 0x10015230, 0, 0xffffffff, 'x', "Interrupt Mask Register, Port C" },
+{ "PTC_ISR", 0x10015234, 0, 0xffffffff, 'x', "Interrupt Status Register, Port C" },
+{ "PTC_GPR", 0x10015238, 0, 0xffffffff, 'x', "General Purpose Register, Port C" },
+{ "PTC_SWR", 0x1001523c, 0, 0xffffffff, 'x', "Software Reset Register, Port C" },
+{ "PTC_PUEN", 0x10015240, 0, 0xffffffff, 'x', "Pull_up Enable Register, Port C" },
+{ "PTD_DDIR", 0x10015300, 0, 0xffffffff, 'x', "Data Direction Register, Port D" },
+{ "PTD_OCR1", 0x10015304, 0, 0xffffffff, 'x', "Output Configuration Register 1 (OCR1), Port" },
+{ "PTD_OCR2", 0x10015308, 0, 0xffffffff, 'x', "Output Configuration Register 2 (OCR2), Port" },
+{ "PTD_ICONFA1", 0x1001530c, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA1), Port" },
+{ "PTD_ICONFA2", 0x10015310, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA2), Port" },
+{ "PTD_ICONFB1", 0x10015314, 0, 0xffffffff, 'x', "Input Configuration Register B1 (ICONFB1), Port" },
+{ "PTD_ICONFB2", 0x10015318, 0, 0xffffffff, 'x', "Input Configuration Register B2 (ICONFB2), Port" },
+{ "PTD_DR", 0x1001531c, 0, 0xffffffff, 'x', "Data Register, Port D" },
+{ "PTD_GIUS", 0x10015320, 0, 0xffffffff, 'x', "GPIO In Use Register, Port D" },
+{ "PTD_SSR", 0x10015324, 0, 0xffffffff, 'x', "Sample Status Register, Port D" },
+{ "PTD_ICR1", 0x10015328, 0, 0xffffffff, 'x', "Interrupt Configuration Register 1, Port D" },
+{ "PTD_ICR2", 0x1001532C, 0, 0xffffffff, 'x', "Interrupt Configuration Register 2, Port D" },
+{ "PTD_IMR", 0x10015330, 0, 0xffffffff, 'x', "Interrupt Mask Register, Port D" },
+{ "PTD_ISR", 0x10015334, 0, 0xffffffff, 'x', "Interrupt Status Register, Port D" },
+{ "PTD_GPR", 0x10015338, 0, 0xffffffff, 'x', "General Purpose Register, Port D" },
+{ "PTD_SWR", 0x1001533c, 0, 0xffffffff, 'x', "Software Reset Register, Port D" },
+{ "PTD_PUEN", 0x10015340, 0, 0xffffffff, 'x', "Pull_up Enable Register, Port D" },
+{ "PTE_DDIR", 0x10015400, 0, 0xffffffff, 'x', "Data Direction Register, Port E" },
+{ "PTE_OCR1", 0x10015404, 0, 0xffffffff, 'x', "Output Configuration Register 1 (OCR1), Port" },
+{ "PTE_OCR2", 0x10015408, 0, 0xffffffff, 'x', "Output Configuration Register 2 (OCR2), Port" },
+{ "PTE_ICONFA1", 0x1001540c, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA1), Port" },
+{ "PTE_ICONFA2", 0x10015410, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA2), Port" },
+{ "PTE_ICONFB1", 0x10015414, 0, 0xffffffff, 'x', "Input Configuration Register B1 (ICONFB1), Port" },
+{ "PTE_ICONFB2", 0x10015418, 0, 0xffffffff, 'x', "Input Configuration Register B2 (ICONFB2), Port" },
+{ "PTE_DR", 0x1001541c, 0, 0xffffffff, 'x', "Data Register, Port E" },
+{ "PTE_GIUS", 0x10015420, 0, 0xffffffff, 'x', "GPIO In Use Register, Port E" },
+{ "PTE_SSR", 0x10015424, 0, 0xffffffff, 'x', "Sample Status Register, Port E" },
+{ "PTE_ICR1", 0x10015428, 0, 0xffffffff, 'x', "Interrupt Configuration Register 1, Port E" },
+{ "PTE_ICR2", 0x1001542C, 0, 0xffffffff, 'x', "Interrupt Configuration Register 2, Port E" },
+{ "PTE_IMR", 0x10015430, 0, 0xffffffff, 'x', "Interrupt Mask Register, Port E" },
+{ "PTE_ISR", 0x10015434, 0, 0xffffffff, 'x', "Interrupt Status Register, Port E" },
+{ "PTE_GPR", 0x10015438, 0, 0xffffffff, 'x', "General Purpose Register, Port E" },
+{ "PTE_SWR", 0x1001543c, 0, 0xffffffff, 'x', "Software Reset Register, Port E" },
+{ "PTE_PUEN", 0x10015440, 0, 0xffffffff, 'x', "Pull_up Enable Register, Port E" },
+{ "PTF_DDIR", 0x10015500, 0, 0xffffffff, 'x', "Data Direction Register, Port F" },
+{ "PTF_OCR1", 0x10015504, 0, 0xffffffff, 'x', "Output Configuration Register 1 (OCR1), Port" },
+{ "PTF_OCR2", 0x10015508, 0, 0xffffffff, 'x', "Output Configuration Register 2 (OCR2), Port" },
+{ "PTF_ICONFA1", 0x1001550C, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA1), Port" },
+{ "PTF_ICONFA2", 0x10015510, 0, 0xffffffff, 'x', "Input Configuration Register A1 (ICONFA2), Port" },
+{ "PTF_ICONFB1", 0x10015514, 0, 0xffffffff, 'x', "Input Configuration Register B1 (ICONFB1), Port" },
+{ "PTF_ICONFB2", 0x10015518, 0, 0xffffffff, 'x', "Input Configuration Register B2 (ICONFB2), Port" },
+{ "PTF_DR", 0x1001551c, 0, 0xffffffff, 'x', "Data Register, Port F" },
+{ "PTF_GIUS", 0x10015520, 0, 0xffffffff, 'x', "GPIO In Use Register, Port F" },
+{ "PTF_SSR", 0x10015524, 0, 0xffffffff, 'x', "Sample Status Register, Port F" },
+{ "PTF_ICR1", 0x10015528, 0, 0xffffffff, 'x', "Interrupt Configuration Register 1, Port F" },
+{ "PTF_ICR2", 0x1001552C, 0, 0xffffffff, 'x', "Interrupt Configuration Register 2, Port F" },
+{ "PTF_IMR", 0x10015530, 0, 0xffffffff, 'x', "Interrupt Mask Register, Port F" },
+{ "PTF_ISR", 0x10015534, 0, 0xffffffff, 'x', "Interrupt Status Register, Port F" },
+{ "PTF_GPR", 0x10015538, 0, 0xffffffff, 'x', "General Purpose Register, Port F" },
+{ "PTF_SWR", 0x1001553c, 0, 0xffffffff, 'x', "Software Reset Register, Port F" },
+{ "PTF_PUEN", 0x10015540, 0, 0xffffffff, 'x', "Pull_up Enable Register, Port F" },
+{ "PMASK", 0x10015600, 0, 0xffffffff, 'x', "GPIO Port Interrupt Mask" },
+// AUDMUX
+{ "HPCR1", 0x10016000, 0, 0xffffffff, 'x', "Host Port Configuration Register 1" },
+{ "HPCR2", 0x10016004, 0, 0xffffffff, 'x', "Host Port Configuration Register 2" },
+{ "HPCR3", 0x10016008, 0, 0xffffffff, 'x', "Host Port Configuration Register 3" },
+{ "PPCR1", 0x10016010, 0, 0xffffffff, 'x', "Peripheral Port Configuration Register 1" },
+{ "PPCR2", 0x10016014, 0, 0xffffffff, 'x', "Peripheral Port Configuration Register 2" },
+{ "PPCR3", 0x1001601C, 0, 0xffffffff, 'x', "Peripheral Port Configuration Register 3" },
+// CSPI3
+{ "RXDATA3", 0x10017000, 0, 0xffffffff, 'x', "Receive Data Register 3" },
+{ "TXDATA3", 0x10017004, 0, 0xffffffff, 'x', "Transmit Data Register 3" },
+{ "CONTROL_REG3", 0x10017008, 0, 0xffffffff, 'x', "CSPI Control Register 3" },
+{ "INT_REG3", 0x1001700C, 0, 0xffffffff, 'x', "Interrupt Control/Status Register 3" },
+{ "TEST_REG3", 0x10017010, 0, 0xffffffff, 'x', "CSPI Test Register 3" },
+{ "PERIOD3", 0x10017014, 0, 0xffffffff, 'x', "CSPI Sample Period Control Register 3" },
+{ "CSPI_DMA3", 0x10017018, 0, 0xffffffff, 'x', "CSPI DMA Register 3" },
+{ "CSPI_RESET3", 0x1001701C, 0, 0xffffffff, 'x', "CSPI Soft Reset Register 3" },
+// MSHC
+{ "COMMAND_REG", 0x10018000, 0, 0xffffffff, 'x', "MSHC Command Register" },
+{ "DATA_REG", 0x10018008, 0, 0xffffffff, 'x', "MSHC Data Register" },
+{ "STATUS_REG", 0x10018010, 0, 0xffffffff, 'x', "MSHC Status Register" },
+{ "SYSTEM_REG", 0x10018018, 0, 0xffffffff, 'x', "MSHC System Register" },
+// GPT4
+{ "TCTL4", 0x10019000, 0, 0xffffffff, 'x', "GPT Control Register 4" },
+{ "TPRER4", 0x10019004, 0, 0xffffffff, 'x', "GPT Prescaler Register 4" },
+{ "TCMP4", 0x10019008, 0, 0xffffffff, 'x', "GPT Compare Register 4" },
+{ "TCR4", 0x1001900C, 0, 0xffffffff, 'x', "GPT Capture Register 4" },
+{ "TCN4", 0x10019010, 0, 0xffffffff, 'x', "GPT Counter Register 4" },
+{ "TSTAT4", 0x10019014, 0, 0xffffffff, 'x', "GPT Status Register 4" },
+// GPT5
+{ "TCTL5", 0x1001A000, 0, 0xffffffff, 'x', "GPT Control Register 5" },
+{ "TPRER5", 0x1001A004, 0, 0xffffffff, 'x', "GPT Prescaler Register 5" },
+{ "TCMP5", 0x1001A008, 0, 0xffffffff, 'x', "GPT Compare Register 5" },
+{ "TCR5", 0x1001A00C, 0, 0xffffffff, 'x', "GPT Capture Register 5" },
+{ "TCN5", 0x1001A010, 0, 0xffffffff, 'x', "GPT Counter Register 5" },
+{ "TSTAT5", 0x1001A014, 0, 0xffffffff, 'x', "GPT Status Register 5" },
+// UART5
+{ "UXRD_5", 0x1001B000, 0, 0xffffffff, 'x', "UART5 Receiver Register" },
+{ "UTXD_5", 0x1001B040, 0, 0xffffffff, 'x', "UART5 Transmitter Register" },
+{ "UCR1_5", 0x1001B080, 0, 0xffffffff, 'x', "UART5 Control Register" },
+{ "UCR2_5", 0x1001B084, 0, 0xffffffff, 'x', "UART5 Control Register 2" },
+{ "UCR3_5", 0x1001B088, 0, 0xffffffff, 'x', "UART5 Control Register 3" },
+{ "UCR4_5", 0x1001B08C, 0, 0xffffffff, 'x', "UART5 Control Register 4" },
+{ "UFCR_5", 0x1001B090, 0, 0xffffffff, 'x', "UART5 FIFO Control Register" },
+{ "USR1_5", 0x1001B094, 0, 0xffffffff, 'x', "UART5 Status Register 1" },
+{ "USR2_5", 0x1001B098, 0, 0xffffffff, 'x', "UART5 Status Register 2" },
+{ "UESC_5", 0x1001B09C, 0, 0xffffffff, 'x', "UART5 Escape Character Register" },
+{ "UTIM_5", 0x1001B0A0, 0, 0xffffffff, 'x', "UART5 Escape Timer Register" },
+{ "UBIR_5", 0x1001B0A4, 0, 0xffffffff, 'x', "UART5 BRM Incremental Register" },
+{ "UBMR_5", 0x1001B0A8, 0, 0xffffffff, 'x', "UART5 BRM Modulator Register" },
+{ "UBRC_5", 0x1001B0AC, 0, 0xffffffff, 'x', "UART5 Baud Rate Count Register" },
+{ "ONEMS_5", 0x1001B0B0, 0, 0xffffffff, 'x', "UART5 One Millisecond Register" },
+{ "UTS_5", 0x1001B0B4, 0, 0xffffffff, 'x', "UART5 Test Register 1" },
+// UART6
+{ "UXRD_6", 0x1001C000, 0, 0xffffffff, 'x', "UART6 Receiver Register" },
+{ "UTXD_6", 0x1001C040, 0, 0xffffffff, 'x', "UART6 Transmitter Register" },
+{ "UCR1_6", 0x1001C080, 0, 0xffffffff, 'x', "UART6 Control Register" },
+{ "UCR2_6", 0x1001C084, 0, 0xffffffff, 'x', "UART6 Control Register 2" },
+{ "UCR3_6", 0x1001C088, 0, 0xffffffff, 'x', "UART6 Control Register 3" },
+{ "UCR4_6", 0x1001C08C, 0, 0xffffffff, 'x', "UART6 Control Register 4" },
+{ "UFCR_6", 0x1001C090, 0, 0xffffffff, 'x', "UART6 FIFO Control Register" },
+{ "USR1_6", 0x1001C094, 0, 0xffffffff, 'x', "UART6 Status Register 1" },
+{ "USR2_6", 0x1001C098, 0, 0xffffffff, 'x', "UART6 Status Register 2" },
+{ "UESC_6", 0x1001C09C, 0, 0xffffffff, 'x', "UART6 Escape Character Register" },
+{ "UTIM_6", 0x1001C0A0, 0, 0xffffffff, 'x', "UART6 Escape Timer Register" },
+{ "UBIR_6", 0x1001C0A4, 0, 0xffffffff, 'x', "UART6 BRM Incremental Register" },
+{ "UBMR_6", 0x1001C0A8, 0, 0xffffffff, 'x', "UART6 BRM Modulator Register" },
+{ "UBRC_6", 0x1001C0AC, 0, 0xffffffff, 'x', "UART6 Baud Rate Count Register" },
+{ "ONEMS_6", 0x1001C0B0, 0, 0xffffffff, 'x', "UART6 One Millisecond Register" },
+{ "UTS_6", 0x1001C0B4, 0, 0xffffffff, 'x', "UART6 Test Register 1" },
+// I2C2
+{ "IADR", 0x1001D000, 0, 0xffffffff, 'x', "I2C Address Register" },
+{ "IFDR", 0x1001D004, 0, 0xffffffff, 'x', "I2C Frequency Divider Register" },
+{ "I2CR", 0x1001D008, 0, 0xffffffff, 'x', "I2C Control Register" },
+{ "I2SR", 0x1001D00C, 0, 0xffffffff, 'x', "I2C Status Register" },
+{ "I2DR", 0x1001D010, 0, 0xffffffff, 'x', "I2C Data I/O Register" },
+// SDHC3
+{ "STR_STP_CLK", 0x1001E000, 0, 0xffffffff, 'x', "MMC/SD2 Clock Control Register" },
+{ "STATUS", 0x1001E004, 0, 0xffffffff, 'x', "(Read Only) MMC/SD2 Status Register" },
+{ "CLK_RATE", 0x1001E008, 0, 0xffffffff, 'x', "MMC/SD2 Clock Rate Register" },
+{ "CMD_DAT_CONT", 0x1001E00C, 0, 0xffffffff, 'x', "MMC/SD2 Command and Data Control Register" },
+{ "RESPONSE_TO", 0x1001E010, 0, 0xffffffff, 'x', "MMC/SD2 Response Time Out Register" },
+{ "READ_TO", 0x1001E014, 0, 0xffffffff, 'x', "MMC/SD2 Read Time Out Register" },
+{ "BLK_LEN", 0x1001E018, 0, 0xffffffff, 'x', "MMC/SD2 Block Length Register" },
+{ "NOB", 0x1001E01C, 0, 0xffffffff, 'x', "MMC/SD2 Number of Block Register" },
+{ "REV_NO", 0x1001E020, 0, 0xffffffff, 'x', "MMC/SD2 Revision Number Register" },
+{ "INT_CNTL", 0x1001E024, 0, 0xffffffff, 'x', "MMC/SD2 Interrupt Control Register" },
+{ "CMD", 0x1001E028, 0, 0xffffffff, 'x', "MMC/SD2 Command Number Register" },
+{ "ARGH", 0x1001E02C, 0, 0xffffffff, 'x', "MMC/SD2 Higher Argument Register" },
+{ "ARGL", 0x1001E030, 0, 0xffffffff, 'x', "MMC/SD2 Lower Argument Register" },
+{ "RES_FIFO", 0x1001E034, 0, 0xffffffff, 'x', "(Read Only) MMC/SD2 Response FIFO Register" },
+{ "BUFFER_ACCESS", 0x1001E038, 0, 0xffffffff, 'x', "MMC/SD2 Buffer Access Register" },
+// GPT6
+{ "TCTL6", 0x1001F000, 0, 0xffffffff, 'x', "GPT Control Register 6" },
+{ "TPRER6", 0x1001F004, 0, 0xffffffff, 'x', "GPT Prescaler Register 6" },
+{ "TCMP6", 0x1001F008, 0, 0xffffffff, 'x', "GPT Compare Register 6" },
+{ "TCR6", 0x1001F00C, 0, 0xffffffff, 'x', "GPT Capture Register 6" },
+{ "TCN6", 0x1001F010, 0, 0xffffffff, 'x', "GPT Counter Register 6" },
+{ "TSTAT6", 0x1001F014, 0, 0xffffffff, 'x', "GPT Status Register 6" },
+// AIPI2
+{ "PSR0", 0x10020000, 0, 0xffffffff, 'x', "Peripheral Size Register0" },
+{ "PSR1", 0x10020004, 0, 0xffffffff, 'x', "Peripheral Size Register1" },
+{ "PAR", 0x10020008, 0, 0xffffffff, 'x', "Peripheral Access Register" },
+{ "AAOR", 0x1002000C, 0, 0xffffffff, 'x', "Atomic Access Only Register" },
+// LCDC
+{ "LSSAR", 0x10021000, 0, 0xffffffff, 'x', "LCDC Screen Start Address Register" },
+{ "LSR", 0x10021004, 0, 0xffffffff, 'x', "LCDC Size Register" },
+{ "LVPWR", 0x10021008, 0, 0xffffffff, 'x', "LCDC Virtual Page Width Register" },
+{ "LCPR", 0x1002100C, 0, 0xffffffff, 'x', "LCDC Cursor Position Register" },
+{ "LCWHBR", 0x10021010, 0, 0xffffffff, 'x', "LCDC Cursor Width Height and Blink" },
+{ "LCCMR", 0x10021014, 0, 0xffffffff, 'x', "LCDC Color Cursor Mapping Register" },
+{ "LPCR", 0x10021018, 0, 0xffffffff, 'x', "LCDC Panel Configuration Register" },
+{ "LHCR", 0x1002101C, 0, 0xffffffff, 'x', "LCDC Horizontal Configuration Register" },
+{ "LVCR", 0x10021020, 0, 0xffffffff, 'x', "LCDC Vertical Configuration Register" },
+{ "LPOR", 0x10021024, 0, 0xffffffff, 'x', "LCDC Panning Offset Register" },
+{ "LSCR", 0x10021028, 0, 0xffffffff, 'x', "LCDC Sharp Configuration Register" },
+{ "LPCCR", 0x1002102C, 0, 0xffffffff, 'x', "LCDC PWM Contrast Control Register" },
+{ "LDCR", 0x10021030, 0, 0xffffffff, 'x', "LCDC DMA Control Register" },
+{ "LRMCR", 0x10021034, 0, 0xffffffff, 'x', "LCDC Refresh Mode Control Register" },
+{ "LICR", 0x10021038, 0, 0xffffffff, 'x', "LCDC Interrupt Configuration Register" },
+{ "LIER", 0x1002103C, 0, 0xffffffff, 'x', "LCDC Interrupt Enable Register" },
+{ "LISR", 0x10021040, 0, 0xffffffff, 'x', "LCDC Interrupt Status Register" },
+{ "LGWSAR", 0x10021050, 0, 0xffffffff, 'x', "LCDC Graphic Window Start Address Register" },
+{ "LGWSR", 0x10021054, 0, 0xffffffff, 'x', "LCDC Graphic Window Size Register" },
+{ "LGWVPWR", 0x10021058, 0, 0xffffffff, 'x', "LCDC Graphic Window Virtual Page Width" },
+{ "LGWPOR", 0x1002105C, 0, 0xffffffff, 'x', "LCDC Graphic Window Panning Offset Register" },
+{ "LGWPR", 0x10021060, 0, 0xffffffff, 'x', "LCDC Graphic Window Position Register" },
+{ "LGWCR", 0x10021064, 0, 0xffffffff, 'x', "LCDC Graphic Window Control Register" },
+{ "LGWDCR", 0x10021068, 0, 0xffffffff, 'x', "LCDC Graphic Window DMA Control Register" },
+{ "LAUSCR", 0x10021080, 0, 0xffffffff, 'x', "LCDC Aus mode Control Register" },
+{ "LAUSCCR", 0x10021084, 0, 0xffffffff, 'x', "LCDC Aus mode Cursor Control Register" },
+// SLCD Controller
+{ "DATA_BASE_ADDR", 0x10022000, 0, 0xffffffff, 'x', "SLCD Data Base Address Register" },
+{ "DATA_BUFF_SIZE", 0x10022004, 0, 0xffffffff, 'x', "SLCD Data Buffer Size Register" },
+{ "CMD_BASE_ADDR", 0x10022008, 0, 0xffffffff, 'x', "SLCD Command Buffer Base Address Register" },
+{ "CMD_BUFF_SIZE", 0x1002200C, 0, 0xffffffff, 'x', "SLCD Command Buffer Size Register" },
+{ "CMD_STR_SIZE", 0x10022010, 0, 0xffffffff, 'x', "SLCD Command String Size Register" },
+{ "FIFO_CONFIG", 0x10022014, 0, 0xffffffff, 'x', "SLCD FIFO Configuration Register" },
+{ "LCD_CONFIG", 0x10022018, 0, 0xffffffff, 'x', "SLCD Configuration Register" },
+{ "LCD_XFER_CONFIG", 0x1002201C, 0, 0xffffffff, 'x', "SLCD Transfer Configuration Register" },
+{ "DMA_CTRL_STAT", 0x10022020, 0, 0xffffffff, 'x', "SLCD DMA Control/Status Register" },
+{ "LCD_CLK_CONFIG", 0x10022024, 0, 0xffffffff, 'x', "SLCD Clock Configuration Register" },
+{ "LCD_WRITE_DATA", 0x10022028, 0, 0xffffffff, 'x', "SLCD Write Data Register" },
+// Video Codec
+{ "CodeRun", 0x10023000, 0, 0xffffffff, 'x', "BIT run start" },
+{ "CodeDownLoad", 0x10023004, 0, 0xffffffff, 'x', "Code Download Data Register" },
+{ "HostIntReq", 0x10023008, 0, 0xffffffff, 'x', "Host Interrupt Request to BI" },
+{ "BitIntClear", 0x1002300C, 0, 0xffffffff, 'x', "BIT Interrupt Clear" },
+{ "BitIntSts", 0x10023010, 0, 0xffffffff, 'x', "BIT Interrupt Status" },
+{ "WorkBufAddr", 0x10023100, 0, 0xffffffff, 'x', "Working Buffer Address in External Memory" },
+{ "CodeBufAddr", 0x10023104, 0, 0xffffffff, 'x', "Code Table Size in External Memory" },
+{ "BitStreamCtrl", 0x10023108, 0, 0xffffffff, 'x', "Bit Stream Control" },
+{ "FrameMemCtrl", 0x1002310C, 0, 0xffffffff, 'x', "Frame Memory Control" },
+{ "SramAddr", 0x10023110, 0, 0xffffffff, 'x', "Internal SRAM Base Address" },
+{ "SramSize", 0x10023114, 0, 0xffffffff, 'x', "Internal SRAM Size" },
+{ "BitStreamRdPtr", 0x10023140, 0, 0xffffffff, 'x', "Bit Stream Buffer Read Address" },
+{ "BitStreamWrPtr", 0x10023144, 0, 0xffffffff, 'x', "Bit Stream Buffer Write Address" },
+{ "FrameNum", 0x10023148, 0, 0xffffffff, 'x', "Encoded/Decoded Frame Number" },
+{ "BusyFlag", 0x10023160, 0, 0xffffffff, 'x', "Processing Busy Flag" },
+{ "RunCommand", 0x10023164, 0, 0xffffffff, 'x', "Start/Stop Codec Run Command" },
+{ "RunIndex", 0x10023168, 0, 0xffffffff, 'x', "Run Process Index" },
+{ "RunCodStd", 0x1002316C, 0, 0xffffffff, 'x', "Run Codec Standard" },
+{ "BitBufAddr", 0x10023180, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Bitstream" },
+{ "BitBufSize", 0x10023184, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Bitstream" },
+{ "FrameIntAddrY", 0x10023188, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Temporal" },
+{ "FrameIntAddrCb", 0x1002318C, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Temporal" },
+{ "FrameIntAddrCr", 0x10023190, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Temporal" },
+{ "EncCodStd", 0x10023194, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Encode" },
+{ "EncSrcFormat", 0x10023198, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Encode" },
+{ "EncMp4Para", 0x1002319C, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Encode" },
+{ "Enc263Para", 0x100231A0, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Encode" },
+{ "Enc264Para", 0x100231A4, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Encode" },
+{ "EncSliceMode", 0x100231A8, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Encode" },
+{ "EncGopNum", 0x100231AC, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Encode" },
+{ "EncPictureQs", 0x100231B0, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Encode" },
+{ "RetStatus", 0x100231C0, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Command" },
+{ "RetSrcFormat", 0x100231C4, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Decoded" },
+{ "RetMp4Info", 0x100231C8, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Decoded" },
+{ "Ret263Info", 0x100231CC, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Decoded" },
+{ "Ret264Info", 0x100231D0, 0, 0xffffffff, 'x', "Parameter Registers in sequence initialization. Decoded" },
+{ "FrameSrcAddrY", 0x10023180, 0, 0xffffffff, 'x', "Parameter Register in Processing Running. Source" },
+{ "FrameSrcAddrCb", 0x10023184, 0, 0xffffffff, 'x', "Parameter Register in Processing Running. Source" },
+{ "FrameSrcAddrCr", 0x10023188, 0, 0xffffffff, 'x', "Parameter Register in Processing Running. Source" },
+{ "FrameDecAddrY", 0x1002318C, 0, 0xffffffff, 'x', "Parameter Register in Processing Running. Decode" },
+{ "FrameDecAddrCb", 0x10023190, 0, 0xffffffff, 'x', "Parameter Register in Processing Running. Decode" },
+{ "FrameDecAddrCr", 0x10023194, 0, 0xffffffff, 'x', "Parameter Register in Processing Running. Decode" },
+{ "RetStatus", 0x100231C0, 0, 0xffffffff, 'x', "Parameter Register in Processing Running. Command" },
+// USB On The Go
+{ "UOG_ID", 0x10024000, 0, 0xffffffff, 'x', "ID (UOG_ID)" },
+{ "UOG_HWGENERAL", 0x10024004, 0, 0xffffffff, 'x', "Hardware General (UOG_HWGENERAL)" },
+{ "UOG_HWHOST", 0x10024008, 0, 0xffffffff, 'x', "Host Hardware Parameters (UOG_HWHOST)" },
+{ "UOG_HWDEVICE", 0x1002400C, 0, 0xffffffff, 'x', "Device Hardware Parameters (UOG_HWDEVICE)" },
+{ "UOG_HWTXBUF", 0x10024010, 0, 0xffffffff, 'x', "TX Buffer Hardware Parameters (UOG_HWTXBUF)" },
+{ "UOG_HWRXBUF", 0x10024014, 0, 0xffffffff, 'x', "RX Buffer Hardware Parameters (UOG_HWRXBUF)" },
+{ "GPTIMER0LD", 0x10024080, 0, 0xffffffff, 'x', "General Purpose Timer #0 Load (GPTIMER0LD)" },
+{ "GPTIMER0CTRL", 0x10024084, 0, 0xffffffff, 'x', "General Purpose Timer #0 Controller" },
+{ "GPTIMER0LD", 0x10024088, 0, 0xffffffff, 'x', "General Purpose Timer #1 Load (GPTIMER0LD)" },
+{ "GPTIMER0CTRL", 0x1002...
[truncated message content] |
|
From: <ar...@us...> - 2008-09-09 20:40:48
|
Revision: 877
http://armadeus.svn.sourceforge.net/armadeus/?rev=877&view=rev
Author: artemys
Date: 2008-09-09 20:40:58 +0000 (Tue, 09 Sep 2008)
Log Message:
-----------
[LINUX] correct GPIO driver Makefile (SF bug 1901559)
Modified Paths:
--------------
trunk/target/linux/modules/gpio/Makefile
Modified: trunk/target/linux/modules/gpio/Makefile
===================================================================
--- trunk/target/linux/modules/gpio/Makefile 2008-09-09 12:39:29 UTC (rev 876)
+++ trunk/target/linux/modules/gpio/Makefile 2008-09-09 20:40:58 UTC (rev 877)
@@ -15,10 +15,11 @@
# (preferably use Makefile in parent directory)
else
-BASE_DIR="../../../../buildroot/"
-REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+BASE_DIR="../../../../buildroot"
+REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR)/.config | \
sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
-ARMADEUS_KERNEL_DIR=$(BASE_DIR)build_arm/linux-$(REL)
+BUILD_ARM=`ls $(BASE_DIR) | grep "^build_arm"`
+ARMADEUS_KERNEL_DIR=$(BASE_DIR)/$(BUILD_ARM)/linux-$(REL)
KDIR := $(ARMADEUS_KERNEL_DIR)
PWD := $(shell pwd)
@@ -29,6 +30,7 @@
rm -f *.*o \
rm -f Module.symvers
rm -f .*.cmd
-
+ rm -f *.mod.c
+ rm -rf .tmp_versions/
endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-09-09 12:39:21
|
Revision: 876
http://armadeus.svn.sourceforge.net/armadeus/?rev=876&view=rev
Author: artemys
Date: 2008-09-09 12:39:29 +0000 (Tue, 09 Sep 2008)
Log Message:
-----------
[LINUX] First (working) version of new (faster) MAX1027 driver. Only to test it because more changes will come soon...
Modified Paths:
--------------
trunk/target/linux/modules/Kconfig
trunk/target/linux/modules/Makefile
Added Paths:
-----------
trunk/target/linux/modules/fast_max1027/
trunk/target/linux/modules/fast_max1027/Kconfig
trunk/target/linux/modules/fast_max1027/Makefile
trunk/target/linux/modules/fast_max1027/README
trunk/target/linux/modules/fast_max1027/loadmax.sh
trunk/target/linux/modules/fast_max1027/main.c
Modified: trunk/target/linux/modules/Kconfig
===================================================================
--- trunk/target/linux/modules/Kconfig 2008-08-26 17:15:51 UTC (rev 875)
+++ trunk/target/linux/modules/Kconfig 2008-09-09 12:39:29 UTC (rev 876)
@@ -16,6 +16,8 @@
source "drivers/armadeus/imxlkeypad/Kconfig"
+source "drivers/armadeus/fast_max1027/Kconfig"
+
comment "FPGA related"
depends on ARMADEUS_DRIVERS
Modified: trunk/target/linux/modules/Makefile
===================================================================
--- trunk/target/linux/modules/Makefile 2008-08-26 17:15:51 UTC (rev 875)
+++ trunk/target/linux/modules/Makefile 2008-09-09 12:39:29 UTC (rev 876)
@@ -9,7 +9,7 @@
# Part executed when called from kernel build system:
obj-$(CONFIG_ARMADEUS_DRIVERS) += gpio/ pwm/ backlight/ isp1761/ \
- imxlkeypad/ fpga/
+ imxlkeypad/ fpga/ fast_max1027/
else
Added: trunk/target/linux/modules/fast_max1027/Kconfig
===================================================================
--- trunk/target/linux/modules/fast_max1027/Kconfig (rev 0)
+++ trunk/target/linux/modules/fast_max1027/Kconfig 2008-09-09 12:39:29 UTC (rev 876)
@@ -0,0 +1,10 @@
+#
+#
+
+config ARMADEUS_FAST_MAX1027
+ tristate "Armadeus Max1027 ADC driver (fast version)"
+ default n
+ depends on ARMADEUS_DRIVERS
+ ---help---
+ Fast version (full speed signal digitizing) of the Max1027
+ driver.
Added: trunk/target/linux/modules/fast_max1027/Makefile
===================================================================
--- trunk/target/linux/modules/fast_max1027/Makefile (rev 0)
+++ trunk/target/linux/modules/fast_max1027/Makefile 2008-09-09 12:39:29 UTC (rev 876)
@@ -0,0 +1,33 @@
+#
+# Makefile for the Armadeus Max1027 (fast version)
+#
+
+# Part executed when called from kernel build system:
+ifneq ($(KERNELRELEASE),)
+
+#obj-$(CONFIG_ARMADEUS_FAST_MAX1027) += fast-max1027.o
+obj-m += fast-max1027.o
+fast-max1027-objs := main.o
+
+# Part executed when called from standard make in this directory:
+# (preferably use Makefile in parent directory)
+else
+
+BASE_DIR="../../../../buildroot/"
+REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+ sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+ARMADEUS_KERNEL_DIR=$(BASE_DIR)build_arm/linux-$(REL)
+KDIR := $(ARMADEUS_KERNEL_DIR)
+PWD := $(shell pwd)
+
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+
+clean:
+ rm -f *.*o \
+ rm -f Module.symvers
+ rm -f .*.cmd
+ rm -f *.mod.c
+ rm -rf .tmp_versions/
+endif
+
Property changes on: trunk/target/linux/modules/fast_max1027/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fast_max1027/README
===================================================================
--- trunk/target/linux/modules/fast_max1027/README (rev 0)
+++ trunk/target/linux/modules/fast_max1027/README 2008-09-09 12:39:29 UTC (rev 876)
@@ -0,0 +1,8 @@
+
+To compile:
+make ARCH=arm CROSS_COMPILE=/local/julien/arm-toolchain/buildroot/build_arm_nofpu/staging_dir/bin/arm-linux-
+
+3 modules (gpio.ko, ppdev.ko, loadfpga.ko) will be generated, copy them in your rootfs (/lib/modules).
+copy loadgpio.sh in your /etc/init.d directory on your rootfs and launch it to insert modules and create devices file in /dev
+
+Juliem
Added: trunk/target/linux/modules/fast_max1027/loadmax.sh
===================================================================
--- trunk/target/linux/modules/fast_max1027/loadmax.sh (rev 0)
+++ trunk/target/linux/modules/fast_max1027/loadmax.sh 2008-09-09 12:39:29 UTC (rev 876)
@@ -0,0 +1,31 @@
+#!/bin/ash
+
+#
+# This script will load Armadeus Max1027 module and create /dev/
+#
+
+MAX_DEV_DIR=/dev/max1027
+
+if [ -d "$1" ]; then
+ MAX_MODULES_DIR="$1"
+else
+ KERNEL_VERSION=`uname -r`
+ MAX_MODULES_DIR="/lib/modules/$KERNEL_VERSION/extra/max1027/"
+ echo "Using $MAX_MODULES_DIR as default modules dir as no param was passed"
+fi
+
+insmod $MAX_MODULES_DIR/fast-max1027.ko
+
+MAX_MAJOR=`cat /proc/devices | grep max1027 | cut -d " " -f 1`
+
+if [ "$MAX_MAJOR" == "" ]; then
+ echo "Max1027 module not loaded, exiting"
+ exit 1
+fi
+
+mkdir -p $MAX_DEV_DIR
+
+for channel in 0 1 2 3 4 5 6 7; do
+ minor=$channel
+ mknod $MAX_DEV_DIR/AIN$channel c $MAX_MAJOR $minor
+done
Property changes on: trunk/target/linux/modules/fast_max1027/loadmax.sh
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fast_max1027/main.c
===================================================================
--- trunk/target/linux/modules/fast_max1027/main.c (rev 0)
+++ trunk/target/linux/modules/fast_max1027/main.c 2008-09-09 12:39:29 UTC (rev 876)
@@ -0,0 +1,652 @@
+/*
+ * Armadeus Max1027 driver (fast version)
+ *
+ * Copyright (C) 2006-2008 Armadeus Project / ArmadeusPort Systems
+ * Authors: Nicolas Colombain / Julien Boibessot
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <asm/arch/imx-regs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/interrupt.h> /* request_irq */
+#include <asm/gpio.h> /* imx_gpio_... */
+#include <linux/cdev.h> /* struct cdev */
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/spi/spi.h>
+#include <asm/semaphore.h>
+
+#include <linux/delay.h>
+
+#include <linux/irq.h> /* set_irq_type */
+
+#define DRIVER_NAME "max1027"
+#define DRIVER_VERSION "0.1"
+
+#define MAX1027_EOC_IRQ IRQ_GPIOA(10) // CSI_D6 = PortA 10 IRQ_GPIOA(1) can be used for test
+
+/* Internal registers prefixes */
+#define MAX1027_REG_CONV 0x80
+#define MAX1027_REG_SETUP 0x40
+#define MAX1027_REG_AVG 0x20
+#define MAX1027_REG_RESET 0x10
+#define MAX1027_REG_UNI 0x00
+#define MAX1027_REG_BIPO 0x00
+
+/* register specifics */
+#define MAX1027_CONV_CHSEL(x) ((x&0x0f)<<3)
+#define MAX1027_CONV_SCAN(x) ((x&0x03)<<1)
+#define MAX1027_CONV_TEMP 0x01
+/* All channels and temperature are scanned per conversion */
+#define MAX1027_CONV_DEFAULT (MAX1027_REG_CONV | \
+ MAX1027_CONV_CHSEL(7) | \
+ MAX1027_CONV_SCAN(0) | MAX1027_CONV_TEMP)
+
+#define MAX1027_SETUP_CLKSEL(x) ((x&0x03)<<4)
+#define MAX1027_SETUP_REFSEL(x) ((x&0x03)<<2)
+#define MAX1027_SETUP_DIFFSEL(x) (x&0x03)
+#define MAX1027_SETUP_DIFFSEL_MASK 0x03
+/* Internal clock and single ended configuration following setup cmd */
+#define MAX1027_SETUP_DEFAULT (MAX1027_REG_SETUP | \
+ MAX1027_SETUP_CLKSEL(2) | \
+ MAX1027_SETUP_DIFFSEL(2))
+
+#define MAX1027_AVG_AVGON(x) ((x&0x01)<<4)
+#define MAX1027_AVG_NAVG(x) ((x&0x03)<<2)
+#define MAX1027_AVG_NSCAN(x) (x&0x03)
+
+#define MAX1027_RESET_ALL (0x0|MAX1027_REG_RESET)
+#define MAX1027_RESET_FIFO (0x8|MAX1027_REG_RESET)
+
+#define MAX1027_UNI_UCH(x) ((x&0x0f)<<4)
+#define MAX1027_BIPO_BCH(x) ((x&0x0f)<<4)
+
+#define NB_CHANNELS 8
+#define RESULT_ARRAY_SIZE (NB_CHANNELS+1)
+
+
+// Global variables
+struct max1027_operations *driver_ops;
+static int max1027_major = 0; /* Dynamic major allocation */
+
+
+struct max1027_results {
+ u16 temp; /* in 1/8 °C */
+ u16 ain[NB_CHANNELS];
+};
+
+struct adc_channel {
+ spinlock_t lock;
+
+ int id;
+ int enabled;
+ int initialized;
+ int running;
+ int eoc; /* 1 if convertion ended */
+
+ wait_queue_head_t change_wq;
+ struct fasync_struct *async_queue;
+
+ struct spi_dev *spi; /* clean ?? */
+};
+
+struct max1027 {
+ struct class_device *cdev;
+ struct mutex update_lock;
+ struct max1027_results results;
+ struct adc_channel* channels[NB_CHANNELS];
+ int scan_time; /* in jiffies */
+ unsigned long last_updated; /* in jiffies */
+ /* Shadow registers to hold current configuration */
+ u8 conv_reg;
+ u8 setup_reg;
+ u8 avg_reg;
+ u8 reset_reg;
+ u8 uni_reg;
+ u8 bi_reg;
+
+ struct tasklet_struct tasklet;
+ int conversion_running;
+};
+#define GET_NB_CHANNELS(max1027) (max1027->conv_reg & MASK >> XX)
+
+#define CS_CHANGE(val) 0 /* <-- ça sert à quoi ce truc ??? */
+
+static struct spi_device *current_spi;
+
+struct spi_transfer transfer[NB_CHANNELS+1];
+struct spi_message message;
+u8 buffer[32];
+
+
+// must be used within mutex and outside of IRQ context !!!
+static void max1027_send_cmd( struct spi_device *spi, u8 cmd )
+{
+ u8 buf = cmd;
+ struct max1027 *p_max1027 = dev_get_drvdata(&spi->dev);
+
+ spi_write_then_read(spi, &buf, 1, NULL, 0);
+
+ if( cmd & MAX1027_REG_CONV ) {
+ p_max1027->conv_reg = cmd;
+ }
+ if( cmd & MAX1027_REG_SETUP ) {
+ p_max1027->setup_reg = cmd;
+ }
+ if( cmd & MAX1027_REG_AVG ) {
+ p_max1027->avg_reg = cmd;
+ }
+}
+
+static void max1027_process_results(struct max1027 *max1027)
+{
+ struct adc_channel *channel;
+ u8 msb, lsb;
+ u16 value;
+ int i=0, values_to_read=0, start=0;
+
+ pr_debug("%s", __FUNCTION__);
+
+ if( max1027->conv_reg & MAX1027_CONV_TEMP )
+ values_to_read = NB_CHANNELS+1;
+ else
+ values_to_read = NB_CHANNELS;
+
+#ifdef DEBUG
+ for( i=0; i<values_to_read*2; i++ ) {
+ printk("%02x ", buffer[i]);
+ }
+ printk("\n");
+#endif
+
+ start = 0;
+ /* temp */
+ if( max1027->conv_reg & MAX1027_CONV_TEMP ) {
+ start = 1;
+ msb = buffer[0] & 0x0f;
+ lsb = buffer[1];
+ value = ((msb << 8) | lsb);
+ max1027->results.temp = value;
+ printk("%d°C ", value >> 3); /* 1 unit = 1/8 °C */
+ }
+
+ for( i=start; i<values_to_read; i++ ) {
+ msb = buffer[i*2] & 0x0f;
+ lsb = buffer[(i*2)+1] >> 2;
+ value = (msb << 8) | lsb;
+ max1027->results.ain[i-start] = value;
+ printk("0x%04x ", value);
+ }
+ printk("\n");
+
+
+ /* Wake up waiting userspace apps */
+ pr_debug("EOC for");
+ for (i=0; i < NB_CHANNELS; i++ ) {
+ channel = max1027->channels[i];
+ if (channel != NULL) {
+ if ( channel->running ) {
+ wake_up_interruptible( &(channel->change_wq) );
+ // if (channel->async_queue)
+ // kill_fasync(&channel->async_queue, SIGIO, POLL_IN);
+ pr_debug(" %d", i);
+ channel->running = 0;
+ }
+ }
+ }
+ pr_debug("\n");
+ max1027->conversion_running = 0;
+}
+
+static void max1027_reads_async( struct spi_device *spi, int num_values )
+{
+ int ret, i;
+
+ spi_message_init(&message);
+ message.complete = (void (*)(void *)) max1027_process_results; // (void (*)(void *)) complete;
+ message.context = dev_get_drvdata(¤t_spi->dev); /* cradingue ? */
+
+ i = 0;
+ while (i < num_values) {
+ transfer[i].tx_buf = 0;
+ transfer[i].rx_buf = buffer+(i*2);
+ transfer[i].len = 2;
+ transfer[i].cs_change = CS_CHANGE(i == num_values);
+ spi_message_add_tail(&transfer[i++], &message);
+ }
+
+ ret = spi_async(spi, &message);
+ if (ret)
+ printk(KERN_ERR "%s: error %i in SPI request\n",
+ __FUNCTION__, ret);
+}
+
+
+/*
+ * Handles read() done on /dev/gpioxx
+ */
+static ssize_t max1027_dev_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ unsigned minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ u32 value=0;
+ ssize_t ret = 0;
+ struct adc_channel *channel = file->private_data;
+ struct max1027 *max1027 = dev_get_drvdata(¤t_spi->dev); /* cradingue */
+
+ if (count == 0)
+ return count;
+
+ pr_debug("- %s %d byte(s) on minor %d -> channel %d\n", __FUNCTION__, count, minor, channel->id);
+
+ /* Launch conversion */
+ mutex_lock(&max1027->update_lock);
+ if ( !max1027->conversion_running ) {
+ max1027->conversion_running = 1;
+ max1027_send_cmd( current_spi, MAX1027_REG_CONV | max1027->conv_reg );
+ }
+ mutex_unlock(&max1027->update_lock);
+
+ spin_lock_irq(&channel->lock);
+ channel->running = 1;
+
+ /* Wait until conversion has been done (IRQ triggered) */
+ while (channel->running) {
+ spin_unlock_irq(&channel->lock);
+
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ if (wait_event_interruptible(channel->change_wq, !channel->running))
+ return -ERESTARTSYS;
+
+ spin_lock_irq(&channel->lock);
+ }
+ channel->running = 0;
+
+ /* Read conversion results */
+ value = max1027->results.ain[channel->id]; //get_value_for_channel(channel->id);
+
+ /* Copy result to given userspace buffer */
+ count = min( count, (size_t)sizeof(u32) );
+ if ( copy_to_user(buf, &value, count) ) {
+ ret = -EFAULT;
+ goto out;
+ }
+ ret = count;
+
+out:
+ spin_unlock_irq(&channel->lock);
+ return ret;
+}
+
+/* Tasklet to get results after EOC IRQ */
+/* Tasklets seems to be unable to call spi_xxx too :-( */
+static void read_conversion_results( unsigned long data )
+{
+ struct spi_device *spi = (struct spi_device *)data;
+ struct max1027 *max1027 = dev_get_drvdata(&spi->dev);
+
+ /* Get conversion results from chip */
+ if( max1027->conv_reg & MAX1027_CONV_TEMP )
+ max1027_reads_async(spi, 9);
+ else
+ max1027_reads_async(spi, 8);
+}
+
+/* EOC (End Of Conversion) IRQ handler */
+static irqreturn_t max1027_interrupt(int irq, void *dev_id)
+{
+ struct max1027 *max1027 = dev_id;
+
+ /* schedule task for reading results from chip outside of IRQ */
+ tasklet_schedule( &max1027->tasklet );
+
+ return IRQ_HANDLED;
+}
+
+
+static int max1027_dev_open(struct inode *inode, struct file *file)
+{
+ unsigned minor = MINOR(inode->i_rdev);
+ int ret = 0;
+ struct adc_channel *channel;
+ struct max1027 *max1027 = dev_get_drvdata(¤t_spi->dev); /* suite du cradingue */
+
+ channel = kzalloc(sizeof(struct adc_channel), GFP_KERNEL);
+ if (!channel)
+ goto err_request;
+
+ file->private_data = channel;
+ spin_lock_init(&channel->lock);
+ init_waitqueue_head(&channel->change_wq);
+
+ channel->id = minor;
+
+ /* Something to configure ?? */
+ channel->enabled = 1;
+ channel->running = 0;
+
+ pr_debug("Opening /dev/max1027/AN%d\n", minor);
+ channel->initialized = 1;
+ max1027->channels[minor & 0x07] = channel;
+
+ /* Activate EOC IRQ here ?!! */
+
+ return 0;
+
+err_request:
+ /* what about spinlock & wait_queue ?? */
+ return ret;
+}
+
+static int max1027_dev_release(struct inode *inode, struct file *file)
+{
+ unsigned minor = MINOR(inode->i_rdev);
+ struct adc_channel *channel = file->private_data;
+
+ if( channel->initialized ) {
+ /* something to do here ?? */
+ }
+ kfree(channel);
+ pr_debug("Closing access to /dev/max1027/AN%d\n", minor);
+
+ return 0;
+}
+
+static int max1027_dev_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg )
+{
+ int ret = 0;
+
+ printk( DRIVER_NAME " ## IOCTL received: (0x%x) ##\n", cmd );
+
+ return ret;
+}
+
+static struct file_operations max1027_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+// .write = no_write,
+ .read = max1027_dev_read,
+ .open = max1027_dev_open,
+ .release = max1027_dev_release,
+ .ioctl = max1027_dev_ioctl,
+};
+
+
+// buf value <256 -> max1027 config register
+static ssize_t max1027_set_conversion(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ int val, reg;
+ struct max1027 *p_max1027 = dev_get_drvdata(&spi->dev);
+
+ val = simple_strtol(buf, NULL, 10);
+ printk("%s: 0x%02x\n", __FUNCTION__, val);
+
+ mutex_lock(&p_max1027->update_lock);
+ reg = MAX1027_REG_CONV | (val&0xff);
+ max1027_send_cmd( spi, reg );
+ p_max1027->conv_reg = (u8)reg;
+ mutex_unlock(&p_max1027->update_lock);
+
+ return count;
+}
+
+static ssize_t max1027_get_conversion(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ssize_t ret_size = 0;
+ struct spi_device *spi = to_spi_device(dev);
+ struct max1027 *p_max1027 = dev_get_drvdata(&spi->dev);
+
+ ret_size = sprintf(buf,"0x%2x", p_max1027->conv_reg);
+
+ return ret_size;
+}
+
+
+// buf value <256 -> max1027 config register
+// buf value >=256 -> max1027 Unipolar or Bipolar mode registers
+static ssize_t max1027_set_setup(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ int val, reg;
+ struct max1027 *p_max1027 = dev_get_drvdata(&spi->dev);
+
+ val = simple_strtol(buf, NULL, 10);
+ printk("%s: 0x%02x", __FUNCTION__, val);
+
+ mutex_lock(&p_max1027->update_lock);
+ reg = MAX1027_REG_SETUP | (val&0xff);
+ max1027_send_cmd( spi, reg );
+ p_max1027->setup_reg = (u8)reg;
+ // check whether we need to configure the uni or bipolar mode IOs or not
+ if( ((val&0xff) & MAX1027_SETUP_DIFFSEL_MASK) > MAX1027_SETUP_DIFFSEL(1) ) {
+ max1027_send_cmd( spi, val>>8 );
+ printk("+ 0x%02x", val);
+ }
+ mutex_unlock(&p_max1027->update_lock);
+
+ printk("\n");
+ return count;
+}
+
+static ssize_t max1027_get_setup(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ssize_t ret_size = 0;
+ struct spi_device *spi = to_spi_device(dev);
+ struct max1027 *p_max1027 = dev_get_drvdata(&spi->dev);
+
+ ret_size = sprintf(buf,"0x%2x", p_max1027->setup_reg);
+
+ return ret_size;
+}
+
+// buf value <256 -> max1027 averaging register
+static ssize_t max1027_set_averaging(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ int val;
+ struct max1027 *p_max1027 = dev_get_drvdata(&spi->dev);
+
+ val = simple_strtol(buf, NULL, 10);
+ printk("%s: 0x%02x\n", __FUNCTION__, val);
+
+ mutex_lock(&p_max1027->update_lock);
+ max1027_send_cmd( spi, MAX1027_REG_AVG | (val&0xff) );
+ mutex_unlock(&p_max1027->update_lock);
+
+ return count;
+}
+
+static ssize_t max1027_get_averaging(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ssize_t ret_size = 0;
+ struct spi_device *spi = to_spi_device(dev);
+ struct max1027 *p_max1027 = dev_get_drvdata(&spi->dev);
+
+ ret_size = sprintf(buf,"0x%2x", p_max1027->avg_reg);
+
+ return ret_size;
+}
+
+static DEVICE_ATTR(conversion, S_IWUSR | S_IRUGO, max1027_get_conversion, max1027_set_conversion);
+static DEVICE_ATTR(setup, S_IWUSR | S_IRUGO, max1027_get_setup, max1027_set_setup);
+static DEVICE_ATTR(averaging, S_IWUSR | S_IRUGO, max1027_get_averaging, max1027_set_averaging);
+/* Unipolar / Bipolar are set with Setup register specials modes !!!
+static DEVICE_ATTR(unipolar, S_IWUSR, NULL, max1027_unipolar);
+static DEVICE_ATTR(bipolar, S_IWUSR, NULL, max1027_bipolar);*/
+
+#define SYSFS_ERROR_STRING "Unable to create sysfs attribute for max1027"
+
+int static max1027_create_sys_entries(struct spi_device *spi)
+{
+ int status = 0;
+
+ if ((status = device_create_file(&spi->dev, &dev_attr_conversion))) {
+ printk(KERN_WARNING SYSFS_ERROR_STRING " Conversion register\n");
+ goto end;
+ }
+
+ if ((status = device_create_file(&spi->dev, &dev_attr_setup))) {
+ printk(KERN_WARNING SYSFS_ERROR_STRING " Setup register\n");
+ goto end;
+ }
+
+ if ((status = device_create_file(&spi->dev, &dev_attr_averaging))) {
+ printk(KERN_WARNING SYSFS_ERROR_STRING " Averaging register\n");
+ goto end;
+ }
+
+end:
+ return status;
+}
+
+static int __devinit max1027_probe(struct spi_device *spi)
+{
+ struct max1027 *max1027;
+ static int result;
+ int i;
+
+ pr_debug("%s", __FUNCTION__);
+
+ max1027 = kzalloc(sizeof(struct max1027), GFP_KERNEL);
+ if (!max1027)
+ return -ENOMEM;
+ mutex_init(&max1027->update_lock);
+ for (i=0; i < NB_CHANNELS; i++ ) {
+ max1027->channels[i] = NULL;
+ }
+
+ /* Register the driver as character device by getting a major number */
+ result = register_chrdev(max1027_major, DRIVER_NAME, &max1027_fops);
+ if (result < 0)
+ {
+ printk(KERN_WARNING DRIVER_NAME ": can't get major %d\n", max1027_major);
+ return result;
+ }
+ if( max1027_major == 0 ) max1027_major = result; /* dynamic Major allocation */
+
+ /* Request interrupt for EOC */
+ result = request_irq( MAX1027_EOC_IRQ , max1027_interrupt, 0, DRIVER_NAME, max1027 );
+ if( result )
+ goto err_irq;
+ imx_gpio_mode( GPIO_PORTA | 10 | GPIO_IN | GPIO_GIUS );
+ set_irq_type( MAX1027_EOC_IRQ, IRQF_TRIGGER_FALLING );
+
+ /* Create /sys entries */
+ /* sysfs hook */
+ dev_set_drvdata(&spi->dev, max1027);
+ current_spi = spi; /* <<-- cradingue !! trouver comment faire autrement !! */
+
+ result = max1027_create_sys_entries(spi);
+ if (result)
+ goto err_sys;
+
+ tasklet_init( &max1027->tasklet, read_conversion_results, (unsigned long)spi);
+ max1027->conversion_running = 0;
+
+ /* setup spi_device */
+ spi->bits_per_word = 8;
+ spi_setup(spi);
+ /* configure the MAX */
+ max1027_send_cmd( spi, MAX1027_RESET_ALL );
+ max1027->conv_reg = (u8)MAX1027_CONV_DEFAULT;
+ max1027_send_cmd( spi, MAX1027_SETUP_DEFAULT );
+
+ printk( DRIVER_NAME " v" DRIVER_VERSION " successfully probed !\n");
+ return(0);
+
+err_sys:
+ free_irq(MAX1027_EOC_IRQ, max1027);
+err_irq:
+ unregister_chrdev(max1027_major, DRIVER_NAME);
+
+ return result;
+}
+
+static int __devexit max1027_remove(struct spi_device *spi)
+{
+ struct max1027 *max1027 = dev_get_drvdata(&spi->dev);
+ int i;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ device_remove_file(&spi->dev, &dev_attr_conversion);
+ device_remove_file(&spi->dev, &dev_attr_setup);
+ device_remove_file(&spi->dev, &dev_attr_averaging);
+
+ tasklet_kill( &max1027->tasklet );
+
+ /* De-register from /dev interface */
+ unregister_chrdev(max1027_major, DRIVER_NAME);
+
+ free_irq(MAX1027_EOC_IRQ, max1027);
+
+ dev_set_drvdata(&spi->dev, NULL);
+
+ for (i=0; i < NB_CHANNELS; i++) {
+ kfree( max1027->channels[i] );
+ }
+ kfree(max1027);
+
+ return 0;
+}
+
+
+static struct spi_driver max1027_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = max1027_probe,
+ .remove = __devexit_p(max1027_remove),
+};
+
+static int __init max1027_init(void)
+{
+ return spi_register_driver(&max1027_driver);
+}
+
+static void __exit max1027_exit(void)
+{
+ spi_unregister_driver(&max1027_driver);
+}
+
+module_init(max1027_init);
+module_exit(max1027_exit);
+
+
+MODULE_AUTHOR("Julien Boibessot / Nicolas Colombain - Armadeus Systems");
+MODULE_DESCRIPTION("Max1027 driver");
+MODULE_LICENSE("GPL");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-08-26 17:15:40
|
Revision: 875
http://armadeus.svn.sourceforge.net/armadeus/?rev=875&view=rev
Author: artemys
Date: 2008-08-26 17:15:51 +0000 (Tue, 26 Aug 2008)
Log Message:
-----------
[TOOLS] Correct small bug in patch generation tool
Modified Paths:
--------------
trunk/target/linux/Makefile
Modified: trunk/target/linux/Makefile
===================================================================
--- trunk/target/linux/Makefile 2008-08-21 11:30:51 UTC (rev 874)
+++ trunk/target/linux/Makefile 2008-08-26 17:15:51 UTC (rev 875)
@@ -5,7 +5,7 @@
include $(BUILDROOT_DIR)/.config
LINUX_VERSION:=$(shell echo $(BR2_PACKAGE_LINUX_VERSION))
-TARBALL_DIR:=$(shell echo $(BR2_DL_DIR)) #/local/downloads
+TARBALL_DIR:=$(shell echo $(BR2_DL_DIR))
BUILD_DIR=$(BUILDROOT_DIR)/build_arm
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jo...@us...> - 2008-08-21 11:30:41
|
Revision: 874
http://armadeus.svn.sourceforge.net/armadeus/?rev=874&view=rev
Author: jorasse
Date: 2008-08-21 11:30:51 +0000 (Thu, 21 Aug 2008)
Log Message:
-----------
[uboot] introduce new target
Modified Paths:
--------------
branches/apf2/buildroot/target/device/armadeus/apf27/Makefile.in
Modified: branches/apf2/buildroot/target/device/armadeus/apf27/Makefile.in
===================================================================
--- branches/apf2/buildroot/target/device/armadeus/apf27/Makefile.in 2008-08-14 12:34:46 UTC (rev 873)
+++ branches/apf2/buildroot/target/device/armadeus/apf27/Makefile.in 2008-08-21 11:30:51 UTC (rev 874)
@@ -1,5 +1,5 @@
-U-BOOT_TARGET_NAME=pcm038
+U-BOOT_TARGET_NAME=apf27
LINUX_FORMAT=uImage
LINUX_KCONFIG=$(ARMADEUS_CONFIG_PATH)/linux-$(BR2_PACKAGE_LINUX_VERSION).config
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <Fa...@us...> - 2008-08-14 12:34:37
|
Revision: 873
http://armadeus.svn.sourceforge.net/armadeus/?rev=873&view=rev
Author: FabM
Date: 2008-08-14 12:34:46 +0000 (Thu, 14 Aug 2008)
Log Message:
-----------
[DRIVERS][POD] podscript without tree cmd
Modified Paths:
--------------
trunk/target/linux/modules/fpga/podscript.sh
Modified: trunk/target/linux/modules/fpga/podscript.sh
===================================================================
--- trunk/target/linux/modules/fpga/podscript.sh 2008-08-11 08:21:10 UTC (rev 872)
+++ trunk/target/linux/modules/fpga/podscript.sh 2008-08-14 12:34:46 UTC (rev 873)
@@ -25,17 +25,19 @@
line=""
-for i in `tree -fid $FPGADIR$PODDIR | grep -v "$PODDIR\$" | grep "$PODDIR"`
+for i in `ls $FPGADIR$PODDIR`
do
- echo $i
- IFS='/'
- name=(${i})
+ if [ -d $FPGADIR$PODDIR/$i ]
+ then
+ echo $i
+ name=$i
-echo """
-source \"drivers/armadeus/fpga/POD/${name[5]}/Kconfig\"
+ echo """
+source \"drivers/armadeus/fpga/POD/$name/Kconfig\"
""" >> "${FPGADIR}${PODDIR}/Kconfig"
- line="${line} ${name[5]}/"
+ line="${line} $name/"
+ fi;
done;
# fill Makefile
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <Fa...@us...> - 2008-08-11 08:21:05
|
Revision: 872
http://armadeus.svn.sourceforge.net/armadeus/?rev=872&view=rev
Author: FabM
Date: 2008-08-11 08:21:10 +0000 (Mon, 11 Aug 2008)
Log Message:
-----------
[Drivers][POD] Error patched
Added Paths:
-----------
trunk/target/linux/modules/fpga/POD/void/
trunk/target/linux/modules/fpga/POD/void/Kconfig
trunk/target/linux/modules/fpga/POD/void/Makefile
trunk/target/linux/modules/fpga/POD/void/void.c
Added: trunk/target/linux/modules/fpga/POD/void/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/POD/void/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/POD/void/Kconfig 2008-08-11 08:21:10 UTC (rev 872)
@@ -0,0 +1,10 @@
+#
+#
+
+config VOID_DRIVER
+ tristate "Useless, just to avoid error"
+ default n
+ depends on POD_DRIVERS
+ ---help---
+ Useless, just to avoid error
+
Added: trunk/target/linux/modules/fpga/POD/void/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/POD/void/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/POD/void/Makefile 2008-08-11 08:21:10 UTC (rev 872)
@@ -0,0 +1,29 @@
+#
+# Makefile for a generic Armadeus drivers
+#
+
+# Part executed when called from kernel build system:
+ifneq ($(KERNELRELEASE),)
+
+obj-$(CONFIG_VOID_DRIVER) += void.o
+
+# Part executed when called from standard make in this directory:
+# (preferably use Makefile in parent directory)
+else
+
+BASE_DIR="../../../../../../buildroot/"
+REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+ sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+ARMADEUS_KERNEL_DIR=$(BASE_DIR)build_arm/linux-$(REL)
+KDIR := $(ARMADEUS_KERNEL_DIR)
+PWD := $(shell pwd)
+
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+
+clean:
+ rm -f *.*o
+ rm -f Module.symvers
+
+endif
+
Property changes on: trunk/target/linux/modules/fpga/POD/void/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fpga/POD/void/void.c
===================================================================
--- trunk/target/linux/modules/fpga/POD/void/void.c (rev 0)
+++ trunk/target/linux/modules/fpga/POD/void/void.c 2008-08-11 08:21:10 UTC (rev 872)
@@ -0,0 +1,45 @@
+/*
+ **********************************************************************
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+
+//
+// Module's initialization function
+//
+static int __init void_init(void)
+{
+ printk("Init void module\n");
+
+ return(0);
+}
+
+//
+// Module's cleanup function
+//
+static void __exit void_exit(void)
+{
+ printk("Leave void module\n");
+}
+
+module_init(void_init);
+module_exit(void_exit);
+MODULE_AUTHOR("Fabien Marteau");
+MODULE_DESCRIPTION("Void driver");
+MODULE_LICENSE("GPL");
Property changes on: trunk/target/linux/modules/fpga/POD/void/void.c
___________________________________________________________________
Added: svn:executable
+ *
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <Fa...@us...> - 2008-08-08 14:41:48
|
Revision: 871
http://armadeus.svn.sourceforge.net/armadeus/?rev=871&view=rev
Author: FabM
Date: 2008-08-08 14:41:56 +0000 (Fri, 08 Aug 2008)
Log Message:
-----------
[DRIVERS][POD] fixing makefile
Added Paths:
-----------
trunk/target/linux/modules/fpga/POD/Kconfig
trunk/target/linux/modules/fpga/POD/Makefile
Added: trunk/target/linux/modules/fpga/POD/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/POD/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/POD/Kconfig 2008-08-08 14:41:56 UTC (rev 871)
@@ -0,0 +1,15 @@
+
+#
+# Armadeus custom drivers configuration
+#
+#
+
+#
+config POD_DRIVERS
+ boolean "Drivers generated by POD"
+ default n
+ depends on ARMADEUS_FPGA_DRIVERS
+ ---help---
+ All drivers for FPGA components
+
+
Added: trunk/target/linux/modules/fpga/POD/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/POD/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/POD/Makefile 2008-08-08 14:41:56 UTC (rev 871)
@@ -0,0 +1,40 @@
+
+#
+# Main Makefile for the Armadeus FPGA related drivers
+#
+# Add your subdirectories to obj- target
+#
+
+ifneq ($(KERNELRELEASE),)
+
+# Part executed when called from kernel build system:
+obj-$(CONFIG_POD_DRIVERS) +=
+
+else
+
+# Part executed when called from standard make in this directory:
+
+BASE_DIR:=../../../../buildroot/
+REL:=$(shell grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | sed -e 's/BR2_PACKAGE_LINUX_VERSION=//' | sed -e 's/"//g')
+#
+ARMADEUS_KERNEL_DIR:=$(BASE_DIR)build_arm/linux-$(REL)
+ifeq ($(LINUX_DIR),)
+LINUX_DIR:=$(ARMADEUS_KERNEL_DIR)
+endif
+PWD:= $(shell pwd)
+
+default:
+ echo "Your Linux source dir is: $(LINUX_DIR)"
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) zImage modules
+
+clean:
+ echo "Your Linux source dir is: $(LINUX_DIR)"
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) clean
+
+install:
+ echo "Installing Armadeus drivers..."
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) INSTALL_MOD_PATH=$(TARGET_DIR) modules_install
+
+endif
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <Fa...@us...> - 2008-08-08 13:29:43
|
Revision: 870
http://armadeus.svn.sourceforge.net/armadeus/?rev=870&view=rev
Author: FabM
Date: 2008-08-08 13:29:53 +0000 (Fri, 08 Aug 2008)
Log Message:
-----------
[drivers][POD] POD integration
Modified Paths:
--------------
trunk/Makefile
Modified: trunk/Makefile
===================================================================
--- trunk/Makefile 2008-08-08 13:29:18 UTC (rev 869)
+++ trunk/Makefile 2008-08-08 13:29:53 UTC (rev 870)
@@ -116,6 +116,10 @@
linux-menuconfig:
+ @if [ ! -e "target/linux/modules/fpga/POD/.pod" ] ; then\
+ target/linux/modules/fpga/podscript.sh ; \
+ fi;
+
@if [ -e "$(LINUX_DIR)/.unpacked" ] ; then \
$(MAKE) -C $(LINUX_DIR) menuconfig ; \
fi;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <Fa...@us...> - 2008-08-08 13:29:10
|
Revision: 869
http://armadeus.svn.sourceforge.net/armadeus/?rev=869&view=rev
Author: FabM
Date: 2008-08-08 13:29:18 +0000 (Fri, 08 Aug 2008)
Log Message:
-----------
[drivers][POD] POD integration
Modified Paths:
--------------
trunk/target/linux/modules/fpga/Kconfig
trunk/target/linux/modules/fpga/Makefile
trunk/target/linux/modules/fpga/others/Wb_button/testbutton.c
trunk/target/linux/modules/fpga/others/Wb_led/Makefile
trunk/target/linux/modules/fpga/others/Wb_led/led.c
trunk/target/linux/modules/fpga/others/Wb_led/led.h
Added Paths:
-----------
trunk/target/linux/modules/fpga/others/Wb_led/testled.c
trunk/target/linux/modules/fpga/podscript.sh
Removed Paths:
-------------
trunk/target/linux/modules/fpga/others/Wb_led/led_specific.h
Modified: trunk/target/linux/modules/fpga/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/Kconfig 2008-08-05 15:28:22 UTC (rev 868)
+++ trunk/target/linux/modules/fpga/Kconfig 2008-08-08 13:29:18 UTC (rev 869)
@@ -15,5 +15,7 @@
source "drivers/armadeus/fpga/others/Kconfig"
+source "drivers/armadeus/fpga/POD/Kconfig"
+
endmenu
Modified: trunk/target/linux/modules/fpga/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/Makefile 2008-08-05 15:28:22 UTC (rev 868)
+++ trunk/target/linux/modules/fpga/Makefile 2008-08-08 13:29:18 UTC (rev 869)
@@ -8,7 +8,7 @@
# Part executed when called from kernel build system:
-obj-$(CONFIG_ARMADEUS_FPGA_DRIVERS) += dev_tools/ others/
+obj-$(CONFIG_ARMADEUS_FPGA_DRIVERS) += dev_tools/ others/ POD/
else
Modified: trunk/target/linux/modules/fpga/others/Wb_button/testbutton.c
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_button/testbutton.c 2008-08-05 15:28:22 UTC (rev 868)
+++ trunk/target/linux/modules/fpga/others/Wb_button/testbutton.c 2008-08-08 13:29:18 UTC (rev 869)
@@ -63,7 +63,7 @@
printf( "Testing button driver\n" );
if(argc < 2){
- perror("invalide arguments number\ntestled <button_filename>\n");
+ perror("invalid arguments number\ntestled <button_filename>\n");
exit(EXIT_FAILURE);
}
Modified: trunk/target/linux/modules/fpga/others/Wb_led/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/Makefile 2008-08-05 15:28:22 UTC (rev 868)
+++ trunk/target/linux/modules/fpga/others/Wb_led/Makefile 2008-08-08 13:29:18 UTC (rev 869)
@@ -2,7 +2,7 @@
# Makefile for the Armadeus Wb_led drivers
#
-BASE_DIR="../../../../../buildroot/"
+BASE_DIR="../../../../../../buildroot/"
REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
@@ -25,7 +25,7 @@
-cp led.ko /tftpboot/
test:
- ~/armadeus/buildroot/build_arm/staging_dir/bin/arm-linux-gcc testled.c -o testled
+ ~/armadeus/buildroot/build_arm/staging_dir/bin/arm-linux-gcc -Wall testled.c -o testled
chmod 755 testled
cp testled /tftpboot/
Modified: trunk/target/linux/modules/fpga/others/Wb_led/led.c
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/led.c 2008-08-05 15:28:22 UTC (rev 868)
+++ trunk/target/linux/modules/fpga/others/Wb_led/led.c 2008-08-08 13:29:18 UTC (rev 869)
@@ -23,275 +23,196 @@
#include "led.h"
-/*********************************
- * simple fpga read/write
- *********************************/
-
-static ssize_t led_fpga_read(void * addr,u16 *data,struct led_dev *dev){
- *data = ioread16(addr);/* read the led value */
- // PDEBUG( "read : value read : %x\n",*data);
- return 2;
-}
-
-static ssize_t led_fpga_write(void * addr,u16 *data,struct led_dev *dev){
- ssize_t retval;
-
- iowrite16(*data,addr);/* write the led value */
- retval = 2;
- return retval;
-}
-
-/* *********************************
- * Sysfs operations
- * *********************************/
-
-static void kobj_release(struct kobject *kobj){
- PDEBUG("led kobject released\n");
-}
-
-static int init_sysinterface(struct led_dev *ldev){
- int ret = 0;
-
- /* initializing kobject to 0 */
- memset(&ldev->kobj,0,sizeof(struct kobject));
- /* set kobject name */
- if(unlikely(ret = kobject_set_name(&ldev->kobj,LED_NAME)))
- goto out;
- /* register */
- if(unlikely(ret=kobject_register(&ldev->kobj)))
- goto out;
- /* register the kobj_type */
- ldev->kobj.ktype = &kobjtype;
- /* add status attribute */
- if(unlikely(ret=sysfs_create_file(&ldev->kobj,&led_status_attr)));
-
-out:
- return ret;
-}
-
-static ssize_t led_show_status(struct kobject *kobj,struct attribute *attr,char *buf){
- ssize_t ret_size = 0;
- struct led_dev *dev;
- u16 data;
-
- dev = container_of(kobj,struct led_dev,kobj);
-
- if(down_interruptible(&dev->sem)){ /* take mutex */
- printk(KERN_WARNING "led_show_status:can't take mutex\n");
- return -ERESTARTSYS;
- }
-
- if((ret_size=led_fpga_read(dev->fpga_virtual_base_address + FPGA_LED,&data,dev))<0)
- goto out;
-
- PDEBUG("data : %d\n",data);
- if(data&0x0001)ret_size = (ssize_t)sprintf(buf,"1\n");
- else ret_size = (ssize_t)sprintf(buf,"0\n");
-
-out:
- up(&dev->sem);
- return ret_size;
-}
-
-static ssize_t led_store_status(struct kobject *kobj,struct attribute *attr,
- const char *buff, size_t size){
- struct led_dev *ldev = container_of(kobj,struct led_dev,kobj);
- u16 data;
-
- if(buff[0]=='1')
- data=0x0001;
- else if(buff[0]=='0')
- data=0x0000;
- else
- return size;
-
- if(down_interruptible(&ldev->sem))
- return -ERESTARTSYS;
-
- size=led_fpga_write(ldev->fpga_virtual_base_address + FPGA_LED,&data,ldev);
-
- up(&ldev->sem);
- return size ;
-}
-
/***********************************
* characters file /dev operations
* *********************************/
-ssize_t led_read(struct file *fildes, char __user *buff, size_t count, loff_t *offp){
- struct led_dev *ldev = fildes->private_data;
- u16 data=0;
- ssize_t retval = 0;
+ssize_t led_read(struct file *fildes, char __user *buff,
+ size_t count, loff_t *offp){
+ struct led_dev *sdev = fildes->private_data;
+ u16 data=0;
+ PDEBUG("Read value\n");
+ if(*offp != 0 ){ /* offset must be 0 */
+ PDEBUG("offset %d\n",(int)*offp);
+ return 0;
+ }
- PDEBUG( "read : offset %d, count %d\n",(int)*offp,(int)count);
- if(down_interruptible(&ldev->sem)) /* take mutex */
- return -ERESTARTSYS;
- if(*offp >= 1){ /* offset must be 0 or 1 */
- goto out;
- }
- if(*offp + count >= 1) /* Only one word can be read */
- count = 1 - *offp;
+ PDEBUG("count %d\n",count);
+ if(count > 2){ /* 16bits max*/
+ count = 2;
+ }
- if((retval = led_fpga_read(ldev->fpga_virtual_base_address + FPGA_LED,&data,ldev))<0)
- goto out;
+ data = ioread16(sdev->fpga_virtual_base_address + sdev->membase);
+ PDEBUG("Read %d at %x\n",data,sdev->membase);
- /* return data for user */
- if(copy_to_user(buff,&data,2)){
- printk(KERN_WARNING "read : copy to user data error\n");
- retval = -EFAULT;
- goto out;
- }
-
- *offp = *offp + count;
- retval = 1;
-
-out:
- up(&ldev->sem); /* free mutex */
- PDEBUG("read : Return value %d\n",(int)retval);
- return retval;
+ /* return data for user */
+ if(copy_to_user(buff,&data,count)){
+ printk(KERN_WARNING "read : copy to user data error\n");
+ return -EFAULT;
+ }
+ return count;
}
-ssize_t led_write(struct file *fildes, const char __user *buff,size_t count, loff_t *offp){
- struct led_dev *ldev = fildes->private_data;
- u16 data=0;
- ssize_t retval = 0;
+ssize_t led_write(struct file *fildes, const char __user *
+ buff,size_t count, loff_t *offp){
+ struct led_dev *sdev = fildes->private_data;
+ u16 data=0;
+ if(*offp != 0){ /* offset must be 0 */
+ PDEBUG("offset %d\n",(int)*offp);
+ return 0;
+ }
- PDEBUG("write : offset %d, count %d\n",(int)*offp,(int)count);
- if(down_interruptible(&ldev->sem))
- return -ERESTARTSYS;
- if(*offp != 0){ /* offset must be 0 */
- goto out;
- }
- if(count != 1) /* Only one word can be read */
- count = 1;
+ PDEBUG("count %d\n",count);
+ if(count > 2){ /* 16 bits max)*/
+ count = 2;
+ }
- if(copy_from_user(&data,buff,1)){
- printk(KERN_WARNING "write : copy from user error\n");
- retval = -EFAULT;
- goto out;
- }
-
- if((retval=led_fpga_write(ldev->fpga_virtual_base_address + FPGA_LED,&data,ldev))<0){
- goto out;
- }
+ if(copy_from_user(&data,buff,count)){
+ printk(KERN_WARNING "write : copy from user error\n");
+ return -EFAULT;
+ }
+
+ PDEBUG("Write %d at %x\n",data,sdev->membase);
+ iowrite16(data,sdev->fpga_virtual_base_address + sdev->membase);
-out:
- up(&ldev->sem);
- return retval;
-
+ return count;
}
+
int led_open(struct inode *inode, struct file *filp){
- /* Allocate and fill any data structure to be put in filp->private_data */
- filp->private_data = container_of(inode->i_cdev,struct led_dev, cdev);
- PDEBUG( "Led opened\n");
- return 0;
+ /* Allocate and fill any data structure to be put in filp->private_data */
+ filp->private_data = container_of(inode->i_cdev,struct led_dev, cdev);
+ PDEBUG( "Led opened\n");
+ return 0;
}
/* ******************************
* Init and release functions
* ******************************/
int led_release(struct inode *inode, struct file *filp){
- PDEBUG( "Led released\n");
- return 0;
+ struct led_dev *dev;
+ dev = container_of(inode->i_cdev,struct led_dev,cdev);
+ PDEBUG( "%s: released\n",dev->name);
+ filp->private_data=NULL;
+ return 0;
}
-/**********************************
- * Module management
- **********************************/
-static int __init led_init(void){
+int register_led(struct plat_led_port *dev){
+ int result = 0; /* error return */
+ int led_major,led_minor;
+ u16 data;
+ struct led_dev *sdev = &led_device[dev->num];
+ PDEBUG("Register %d led\n",dev->num);
+ /* major and minor number */
+ led_major = 253;
+ led_minor = dev->num ;
- int result; /* error return */
- int led_major,led_minor;
- u16 data;
- struct led_dev *sdev;
+ sdev->fpga_virtual_base_address = (void*)IMX_CS1_VIRT;
+ sdev->membase = dev->membase;
- led_major = 253;
- led_minor = 0;
+ /* name and address of the instance */
+ sdev->name = (char *)kmalloc((1+strlen(dev->name))*sizeof(char),GFP_KERNEL);
+ if(sdev->name == NULL){
+ printk("Kmalloc name space error\n");
+ goto error;
+ }
+ if(strncpy(sdev->name,dev->name,1+strlen(dev->name)) < 0){
+ printk("copy error");
+ goto error;
+ }
- /* Allocate a private structure and reference it as driver's data */
- PDEBUG("Allocate a private structure and reference it as driver s data\n");
- sdev = (struct led_dev *)kmalloc(sizeof(struct led_dev),GFP_KERNEL);
- if(sdev == NULL){
- printk(KERN_WARNING "LED: unable to allocate private structure\n");
- return -ENOMEM;
- }
+ /* Get the major and minor device numbers */
+ PDEBUG("%s:Get the major and minor device numbers\n",dev->name);
+ if(led_major){
+ sdev->devno = MKDEV(led_major,led_minor);
+ result = register_chrdev_region(sdev->devno, 1,dev->name);
+ }else{
+ result = alloc_chrdev_region(&sdev->devno,led_minor,1,dev->name);
+ led_major = MAJOR(sdev->devno);
+ }
- /* initiate mutex for accessing led */
- PDEBUG("initiate mutex for accessing led\n");
- init_MUTEX(&sdev->sem);
+ printk(KERN_INFO "%s: MAJOR: %d MINOR: %d\n",dev->name,MAJOR(sdev->devno),MINOR(sdev->devno));
+ if(result < 0){
+ printk(KERN_WARNING "%s: can't get major %d\n",dev->name,led_major);
+ goto error;
+ }
- /* Get the major and minor device numbers */
- PDEBUG("Get the major and minor device numbers\n");
- if(led_major){
- devno = MKDEV(led_major,led_minor);
- result = register_chrdev_region(devno, N_DEV,LED_NAME);
- }else{
- result = alloc_chrdev_region(&devno,led_minor,N_DEV,LED_NAME);
- led_major = MAJOR(devno);
- }
- printk(KERN_INFO "LED: MAJOR: %d MINOR: %d\n",MAJOR(devno),MINOR(devno));
- if(result < 0){
- printk(KERN_WARNING "LED: can't get major %d\n",led_major);
- }
+ /* Init the cdev structure */
+ PDEBUG("%s:Init the cdev structure\n",dev->name);
+ cdev_init(&sdev->cdev,&led_fops);
+ sdev->cdev.owner = THIS_MODULE;
+ sdev->cdev.ops = &led_fops;
- /* Init the cdev structure */
- PDEBUG("Init the cdev structure\n");
- cdev_init(&sdev->cdev,&led_fops);
- sdev->cdev.owner = THIS_MODULE;
+ /* Add the device to the kernel, connecting cdev to major/minor number */
+ PDEBUG("%s:Add the device to the kernel, connecting cdev to major/minor number \n",dev->name);
+ result = cdev_add(&sdev->cdev,sdev->devno,1);
+ if(result){
+ printk(KERN_WARNING "%s: can't add cdev\n",dev->name);
+ goto error;
+ }
- /* Add the device to the kernel, connecting cdev to major/minor number */
- PDEBUG("Add the device to the kernel, connecting cdev to major/minor number \n");
- result = cdev_add(&sdev->cdev,devno,1);
- if(result < 0)printk(KERN_WARNING "LED: can't add cdev\n");
+ /* initialize led value */
+ data=1;
+ iowrite16(data,sdev->fpga_virtual_base_address + sdev->membase);
+ PDEBUG("Wrote %x at %x\n",data,sdev->membase);
- sdev->fpga_virtual_base_address = (void*)IMX_CS1_VIRT;
+ /* OK module inserted ! */
+ printk(KERN_INFO "Led module %s insered\n",dev->name);
+ return 0;
- /* initialyzing sysfs */
- PDEBUG(" initialyzing sysfs\n");
- if(unlikely(result = init_sysinterface(sdev)))
- goto error;
+error:
+ printk(KERN_ERR "%s: not inserted\n",dev->name);
+ free_all(dev);
+ return result;
+}
- /* initialize led value */
- data=1;
- if((result=led_fpga_write(sdev->fpga_virtual_base_address + FPGA_LED,&data,sdev))<0)
- goto error;
+/**********************************
+ * driver probe
+ **********************************/
+static int led_probe(struct platform_device *dev){
- sdev->previousint = jiffies;
- /* OK module inserted ! */
- leddev=sdev;
- printk(KERN_INFO "Led module insered\n");
- return 0;
-
-error:
- printk(KERN_ERR "%s: not inserted\n",LED_NAME);
- free_all();
- return result;
+ /* new code for led with platform device */
+ struct plat_led_port *p = dev->dev.platform_data;
+ int ret,i;
+
+ PDEBUG("Led probing\n");
+ /* register each led in plat_led_port tab */
+ for (i = 0; p->name!=NULL ; p++, i++) {
+ PDEBUG("%s:register led number %d\n",p->name,i);
+ ret = register_led(p);
+ if(ret){
+ printk(KERN_WARNING "Unable to register led %s\n",p->name);
+ }
+ }
+ /* end of new code */
+ PDEBUG("All devices loaded\n");
+ return 0 ;
}
-static void __exit led_exit(void){
- free_all();
+static int led_remove(struct platform_device *dev){
+ struct plat_led_port *p = dev->dev.platform_data;
+ int i;
+ PDEBUG("Removing leds\n");
+ for (i = 0; p->name!=NULL ; p++, i++) {
+ PDEBUG("Remove led %d\n",i);
+ free_all(p);
+ }
+ return 0;
}
-static void free_all(void){
- struct led_dev *sdev;
- sdev = leddev;
-
- /* unregister kobj */
- kobject_unregister(&sdev->kobj);
+static int free_all(struct plat_led_port *dev){
+ struct led_dev *sdev = &led_device[dev->num];
- /* delete the cdev structure */
- cdev_del(&sdev->cdev);
+ PDEBUG("Unregister %s, number %d\n",dev->name,dev->num);
- /* Free the allocated memory */
- kfree(sdev);
+ /* delete the cdev structure */
+ cdev_del(&sdev->cdev);
+ PDEBUG("%s:cdev deleted\n",dev->name);
- /* Release I/O memories */
- release_mem_region(FPGA_BASE_ADDR,FPGA_MEM_SIZE);
-
- /* free major and minor number */
- unregister_chrdev_region(devno,N_DEV);
- printk(KERN_INFO "Led module deleted\n");
+ /* free major and minor number */
+ unregister_chrdev_region(sdev->devno,1);
+ printk(KERN_INFO "%s: Led deleted\n",dev->name);
+ return 0;
}
module_init(led_init);
Modified: trunk/target/linux/modules/fpga/others/Wb_led/led.h
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/led.h 2008-08-05 15:28:22 UTC (rev 868)
+++ trunk/target/linux/modules/fpga/others/Wb_led/led.h 2008-08-08 13:29:18 UTC (rev 869)
@@ -30,18 +30,16 @@
#include <linux/config.h>
#endif
-/* specific header generated by orchestra */
-#include "led_specific.h"
-
/* form module/drivers */
#include <linux/init.h>
#include <linux/module.h>
-/* linux device model */
-#include <linux/kobject.h>
-#include <linux/sysfs.h>
-#include <linux/sysdev.h>
-#include <linux/device.h>
+/* linux device model
+*#include <linux/kobject.h>
+*#include <linux/sysfs.h>
+*#include <linux/sysdev.h>
+*#include <linux/device.h>
+*/
/* for file operations */
#include <linux/fs.h>
@@ -59,6 +57,9 @@
/* hardware addresses */
#include <asm/hardware.h>
+/* for platform device */
+#include <linux/platform_device.h>
+
#endif
/* for debugging messages*/
@@ -68,7 +69,7 @@
#ifdef LED_DEBUG
# ifdef __KERNEL__
/* for kernel spage */
-# define PDEBUG(fmt,args...) printk(KERN_DEBUG "led : " fmt, ##args)
+# define PDEBUG(fmt,args...) printk(KERN_DEBUG "LED : " fmt, ##args)
# else
/* for user space */
# define PDEBUG(fmt,args...) printk(stderr, fmt, ##args)
@@ -77,26 +78,104 @@
# define PDEBUG(fmt,args...) /* no debbuging message */
#endif
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Fabien Marteau <fab...@ar...> - ARMadeus Systems");
-MODULE_DESCRIPTION("Led device driver");
-/* major and minor number */
-#define N_DEV 1
+#define FPGA_BASE_ADDR IMX_CS1_PHYS
+#define FPGA_MEM_SIZE IMX_CS1_SIZE
+#define LED_NUMBER 2
+
+/* platform device */
+struct plat_led_port{
+ const char *name; /* instance name */
+ int num; /* instance number */
+ unsigned int membase; /* ioremap base address */
+};
+
+static struct plat_led_port plat_led_data[] = {
+ {
+ .name = "led0",
+ .num = 0,
+ .membase = 0x04
+ },
+ {
+ .name = "led1",
+ .num = 1,
+ .membase = 0x06
+ },
+ {
+ .name = NULL
+ },
+};
+
+static struct platform_device plat_led_device = {
+ .name = "led",
+ .id = 0,
+ .dev = {
+ .platform_data = plat_led_data
+ },
+};
+
+
+static int led_probe(struct platform_device *plat_led_device);
+static int led_remove(struct platform_device *plat_led_device);
+
+static struct platform_driver plat_led_driver = {
+ .probe = led_probe,
+ .remove = led_remove,
+ .driver = {
+ .name = "led",
+ .owner = THIS_MODULE,
+ },
+};
+
+/************************************
+ * module init and exit
+ ***********************************/
+
+static int __init led_init(void){
+ int ret;
+ PDEBUG("init Led platform driver\n");
+ PDEBUG("Platform driver name %s\n",plat_led_driver.driver.name);
+ ret = platform_driver_register(&plat_led_driver);
+ if(ret){
+ printk(KERN_ERR "Platform driver register error\n");
+ return ret;
+ }
+ PDEBUG("Driver registered\n");
+ ret = platform_device_add(&plat_led_device);
+ if(ret){
+ printk(KERN_ERR "Platform device adding problem\n");
+ return ret;
+ }
+ return 0;
+}
+
+static void __exit led_exit(void){
+ PDEBUG("Exit function \n");
+ platform_driver_unregister(&plat_led_driver);
+ PDEBUG("driver unregistered\n");
+ //platform_device_unregister(&plat_led_device);
+ //PDEBUG("device unregistered\n");
+
+}
+
+/*************************/
/* main device structure */
+/*************************/
struct led_dev{
- struct cdev cdev; /* Char device structure */
- struct semaphore sem; /* Mutex */
- struct kobject kobj; /* kobject for sysfs entry */
- void * fpga_virtual_base_address; /* fpga register base address*/
- unsigned long previousint; /* last interruption time */
+ char *name; /* the name of the instance */
+ struct cdev cdev; /* Char device structure */
+ void * fpga_virtual_base_address; /* fpga register base address*/
+ unsigned int membase; /* base address for instance relative to
+ fpga_virtual_base_address */
+ dev_t devno; /* to store Major and minor numbers */
};
-static void kobj_release(struct kobject *);
-static dev_t devno; /* to store Major and minor numbers */
-static struct led_dev *leddev;
+static struct led_dev led_device[LED_NUMBER];
+
+/******************************/
/* to read write led register */
+/******************************/
ssize_t led_read(struct file *fildes, char __user *buff,
size_t count, loff_t *offp);
@@ -106,7 +185,7 @@
int led_release(struct inode *, struct file *filp);
-struct file_operations led_fops = {
+static struct file_operations led_fops = {
.owner = THIS_MODULE,
.read = led_read,
.write = led_write,
@@ -114,28 +193,14 @@
.release = led_release,
};
-/* Sysfs operation */
-static struct attribute led_status_attr = {
- .name = "status",
- .owner = THIS_MODULE,
- .mode = 0666,
-};
+/****************************
+ * personnal functions
+ ***************************/
-static int init_sysinterface(struct led_dev *pdev);
-static ssize_t led_show_status(struct kobject *kobj,struct attribute *attr,char *buf);
-static ssize_t led_store_status(struct kobject *kobj,struct attribute *attr, const char *buff, size_t size);
+static int free_all(struct plat_led_port *);
-static struct sysfs_ops led_status_fs_ops = {
- .show = led_show_status,
- .store = led_store_status,
-};
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabien Marteau <fab...@ar...> - ARMadeus Systems");
+MODULE_DESCRIPTION("Led device driver");
-struct kobj_type kobjtype = {
- .release = kobj_release,
- .sysfs_ops = &led_status_fs_ops,
-};
-static void free_all(void);
-
-static ssize_t led_fpga_read(void * addr, u16 *data , struct led_dev *dev);
-static ssize_t led_fpga_write(void * addr, u16 *data, struct led_dev *dev);
Deleted: trunk/target/linux/modules/fpga/others/Wb_led/led_specific.h
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/led_specific.h 2008-08-05 15:28:22 UTC (rev 868)
+++ trunk/target/linux/modules/fpga/others/Wb_led/led_specific.h 2008-08-08 13:29:18 UTC (rev 869)
@@ -1,12 +0,0 @@
-/* this file as been generated by orchestra
- * do not modify it manualy
- */
-
-#define FPGA_LED 4
-#define FPGA_IRQ_MASK 0
-#define FPGA_IRQ_PEND 2
-#define FPGA_IRQ_ACK 2
-
-#define FPGA_BASE_ADDR IMX_CS1_PHYS
-#define FPGA_MEM_SIZE IMX_CS1_SIZE
-#define LED_NAME "led"
Added: trunk/target/linux/modules/fpga/others/Wb_led/testled.c
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_led/testled.c (rev 0)
+++ trunk/target/linux/modules/fpga/others/Wb_led/testled.c 2008-08-08 13:29:18 UTC (rev 869)
@@ -0,0 +1,132 @@
+/* a program to write/read values on fpga address map
+ * Fabien Marteau <fab...@ar...>
+ * 7 april 2008
+ * fpgaaccess.h
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ *
+ * A simple driver for reading and writing on
+ * fpga throught a character file /dev/fpgaaccess
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* file management */
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* as name said */
+#include <signal.h>
+
+/* sleep */
+#include <unistd.h>
+
+int fled;
+
+void quit(int pouet){
+ close(fled);
+ exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+ unsigned short i,j;
+
+ /* quit when Ctrl-C pressed */
+ signal(SIGINT, quit);
+
+ j=0;
+
+ printf( "Testing led driver\n" );
+
+ if(argc < 2){
+ perror("invalid arguments number\ntestled <led_filename>\n");
+ exit(EXIT_FAILURE);
+ }
+
+ while(1){
+ i = (i==0)?1:0;
+ fflush(stdout);
+
+ fled=open(argv[1],O_RDWR);
+ if(fled<0){
+ perror("can't open file \n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* read value */
+ if(read(fled,&j,2)<0){
+ perror("read error\n");
+ exit(EXIT_FAILURE);
+ }
+ printf("Read %d\n",j);
+ close(fled);
+ sleep(1);
+
+ fled=open(argv[1],O_RDWR);
+ if(fled<0){
+ perror("can't open file \n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* write value */
+ j = 0;
+ if(write(fled,&j,2)<=0){
+ perror("write error\n");
+ exit(EXIT_FAILURE);
+ }
+ close(fled);
+ printf("Write 0\n");
+ sleep(1);
+
+ fled=open(argv[1],O_RDWR);
+ if(fled<0){
+ perror("can't open file \n");
+ exit(EXIT_FAILURE);
+ }
+ /* read value */
+ if(read(fled,&j,2)<0){
+ perror("read error\n");
+ exit(EXIT_FAILURE);
+ }
+ close(fled);
+ printf("Read %d\n",j);
+ sleep(1);
+
+ fled=open(argv[1],O_RDWR);
+ if(fled<0){
+ perror("can't open file \n");
+ exit(EXIT_FAILURE);
+ }
+ /* write value */
+ j = 1;
+ if(write(fled,&j,2)<=0){
+ perror("write error\n");
+ exit(EXIT_FAILURE);
+ }
+ close(fled);
+ printf("Write 1\n");
+ sleep(1);
+
+ }
+
+ close(fled);
+ exit(0);
+}
Added: trunk/target/linux/modules/fpga/podscript.sh
===================================================================
--- trunk/target/linux/modules/fpga/podscript.sh (rev 0)
+++ trunk/target/linux/modules/fpga/podscript.sh 2008-08-08 13:29:18 UTC (rev 869)
@@ -0,0 +1,86 @@
+#!/bin/bash
+
+FPGADIR="target/linux/modules/fpga"
+PODDIR="/POD"
+
+echo "***********************"
+echo "*Generating POD config*"
+echo "***********************"
+
+echo """
+#
+# Armadeus custom drivers configuration
+#
+#
+
+#
+config POD_DRIVERS
+ boolean \"Drivers generated by POD\"
+ default n
+ depends on ARMADEUS_FPGA_DRIVERS
+ ---help---
+ All drivers for FPGA components
+
+""" > $FPGADIR$PODDIR/Kconfig
+
+
+line=""
+for i in `tree -fid $FPGADIR$PODDIR | grep -v "$PODDIR\$" | grep "$PODDIR"`
+do
+ echo $i
+ IFS='/'
+ name=(${i})
+
+echo """
+source \"drivers/armadeus/fpga/POD/${name[5]}/Kconfig\"
+""" >> "${FPGADIR}${PODDIR}/Kconfig"
+
+ line="${line} ${name[5]}/"
+done;
+
+# fill Makefile
+echo """
+#
+# Main Makefile for the Armadeus FPGA related drivers
+#
+# Add your subdirectories to obj- target
+#
+
+ifneq (\$(KERNELRELEASE),)
+
+# Part executed when called from kernel build system:
+obj-\$(CONFIG_POD_DRIVERS) += ${line}
+
+else
+
+# Part executed when called from standard make in this directory:
+
+BASE_DIR:=../../../../buildroot/
+REL:=\$(shell grep \"BR2_PACKAGE_LINUX_VERSION=\" \$(BASE_DIR).config | \
+ sed -e 's/BR2_PACKAGE_LINUX_VERSION=//' | sed -e 's/\"//g')
+#`grep \"BR2_PACKAGE_LINUX_VERSION=\" \$(BASE_DIR).config | \
+# sed \"s/BR2_PACKAGE_LINUX_VERSION=\\\"//\" | sed \"s/\\\"//\"`
+ARMADEUS_KERNEL_DIR:=\$(BASE_DIR)build_arm/linux-\$(REL)
+ifeq (\$(LINUX_DIR),)
+LINUX_DIR:=\$(ARMADEUS_KERNEL_DIR)
+endif
+PWD:= \$(shell pwd)
+
+default:
+ echo \"Your Linux source dir is: \$(LINUX_DIR)\"
+ \$(MAKE) -C \$(LINUX_DIR) SUBDIRS=\$(PWD) zImage modules
+
+clean:
+ echo \"Your Linux source dir is: \$(LINUX_DIR)\"
+ \$(MAKE) -C \$(LINUX_DIR) SUBDIRS=\$(PWD) clean
+
+install:
+ echo \"Installing Armadeus drivers...\"
+ \$(MAKE) -C \$(LINUX_DIR) SUBDIRS=\$(PWD) INSTALL_MOD_PATH=\$(TARGET_DIR) modules_install
+
+endif
+
+""" > "${FPGADIR}${PODDIR}/Makefile";
+# ok config generated
+touch "$FPGADIR$PODDIR/.pod"
+echo "ok"
Property changes on: trunk/target/linux/modules/fpga/podscript.sh
___________________________________________________________________
Added: svn:executable
+ *
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <Fa...@us...> - 2008-08-05 15:28:29
|
Revision: 868
http://armadeus.svn.sourceforge.net/armadeus/?rev=868&view=rev
Author: FabM
Date: 2008-08-05 15:28:22 +0000 (Tue, 05 Aug 2008)
Log Message:
-----------
[LINUX] Changing fpga driver tree
Modified Paths:
--------------
trunk/target/linux/modules/fpga/Kconfig
trunk/target/linux/modules/fpga/Makefile
Added Paths:
-----------
trunk/target/linux/modules/fpga/POD/
trunk/target/linux/modules/fpga/dev_tools/
trunk/target/linux/modules/fpga/dev_tools/Kconfig
trunk/target/linux/modules/fpga/dev_tools/Makefile
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Kconfig
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Makefile
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.c
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.h
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpgaloader.sh
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.c
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.h
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.c
trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.h
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/.tmp_versions/
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/.tmp_versions/fpgaaccess.mod
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Kconfig
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Makefile
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Module.symvers
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaaccess.c
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaaccess.h
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaregs
trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaregs.c
trunk/target/linux/modules/fpga/others/
trunk/target/linux/modules/fpga/others/Kconfig
trunk/target/linux/modules/fpga/others/Makefile
trunk/target/linux/modules/fpga/others/Wb_button/
trunk/target/linux/modules/fpga/others/Wb_button/Kconfig
trunk/target/linux/modules/fpga/others/Wb_button/Makefile
trunk/target/linux/modules/fpga/others/Wb_button/button.c
trunk/target/linux/modules/fpga/others/Wb_button/button.h
trunk/target/linux/modules/fpga/others/Wb_button/button_specific.h
trunk/target/linux/modules/fpga/others/Wb_button/testbutton.c
trunk/target/linux/modules/fpga/others/Wb_led/
trunk/target/linux/modules/fpga/others/Wb_led/Kconfig
trunk/target/linux/modules/fpga/others/Wb_led/Makefile
trunk/target/linux/modules/fpga/others/Wb_led/led.c
trunk/target/linux/modules/fpga/others/Wb_led/led.h
trunk/target/linux/modules/fpga/others/Wb_led/led_specific.h
trunk/target/linux/modules/fpga/others/i2ctest/
trunk/target/linux/modules/fpga/others/i2ctest/Kconfig
trunk/target/linux/modules/fpga/others/i2ctest/Makefile
trunk/target/linux/modules/fpga/others/i2ctest/README
trunk/target/linux/modules/fpga/others/i2ctest/i2ctest.c
trunk/target/linux/modules/fpga/others/i2ctest/i2ctest.h
trunk/target/linux/modules/fpga/others/ps2keyboard/
trunk/target/linux/modules/fpga/others/ps2keyboard/Kconfig
trunk/target/linux/modules/fpga/others/ps2keyboard/Makefile
trunk/target/linux/modules/fpga/others/ps2keyboard/README
trunk/target/linux/modules/fpga/others/ps2keyboard/core.c
Removed Paths:
-------------
trunk/target/linux/modules/fpga/Wb_button/
trunk/target/linux/modules/fpga/Wb_led/
trunk/target/linux/modules/fpga/fpga_devtools/
trunk/target/linux/modules/fpga/fpgaaccess/
trunk/target/linux/modules/fpga/i2ctest/
trunk/target/linux/modules/fpga/irq_manager/
trunk/target/linux/modules/fpga/ps2keyboard/
trunk/target/linux/modules/fpga/serial/
Modified: trunk/target/linux/modules/fpga/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/Kconfig 2008-08-05 09:44:44 UTC (rev 867)
+++ trunk/target/linux/modules/fpga/Kconfig 2008-08-05 15:28:22 UTC (rev 868)
@@ -6,26 +6,14 @@
#
config ARMADEUS_FPGA_DRIVERS
- boolean "Support for FPGA specific drivers"
+ boolean "Support FPGA specific drivers"
default n
---help---
All drivers for FPGA components
-source "drivers/armadeus/fpga/fpga_devtools/Kconfig"
+source "drivers/armadeus/fpga/dev_tools/Kconfig"
-source "drivers/armadeus/fpga/ps2keyboard/Kconfig"
+source "drivers/armadeus/fpga/others/Kconfig"
-source "drivers/armadeus/fpga/Wb_led/Kconfig"
-
-source "drivers/armadeus/fpga/Wb_button/Kconfig"
-
-source "drivers/armadeus/fpga/i2ctest/Kconfig"
-
-source "drivers/armadeus/fpga/fpgaaccess/Kconfig"
-
-source "drivers/armadeus/fpga/serial/Kconfig"
-
-source "drivers/armadeus/fpga/irq_manager/Kconfig"
-
endmenu
Modified: trunk/target/linux/modules/fpga/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/Makefile 2008-08-05 09:44:44 UTC (rev 867)
+++ trunk/target/linux/modules/fpga/Makefile 2008-08-05 15:28:22 UTC (rev 868)
@@ -8,8 +8,7 @@
# Part executed when called from kernel build system:
-obj-$(CONFIG_ARMADEUS_FPGA_DRIVERS) += ps2keyboard/ fpga_devtools/ Wb_led/ Wb_button/ \
- i2ctest/ fpgaaccess/ serial/ irq_manager/
+obj-$(CONFIG_ARMADEUS_FPGA_DRIVERS) += dev_tools/ others/
else
Added: trunk/target/linux/modules/fpga/dev_tools/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/Kconfig 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,12 @@
+#
+# Armadeus custom drivers configuration
+#
+config ARMADEUS_FPGA_TEST
+ boolean "Driver for configuring and testing fpga"
+ default n
+ depends on ARMADEUS_FPGA_DRIVERS
+ ---help---
+ All drivers for FPGA components
+
+source "drivers/armadeus/fpga/dev_tools/fpga_devtools/Kconfig"
+source "drivers/armadeus/fpga/dev_tools/fpgaaccess/Kconfig"
Added: trunk/target/linux/modules/fpga/dev_tools/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/Makefile 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,41 @@
+#
+# Main Makefile for the Armadeus FPGA related drivers
+#
+# Add your subdirectories to obj- target
+#
+
+ifneq ($(KERNELRELEASE),)
+
+# Part executed when called from kernel build system:
+
+obj-$(CONFIG_ARMADEUS_FPGA_TEST) += fpga_devtools/ fpgaaccess/
+
+else
+
+# Part executed when called from standard make in this directory:
+
+BASE_DIR:=../../../../buildroot/
+REL:=$(shell grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+ sed -e 's/BR2_PACKAGE_LINUX_VERSION=//' | sed -e 's/"//g')
+#`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+# sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+ARMADEUS_KERNEL_DIR:=$(BASE_DIR)build_arm/linux-$(REL)
+ifeq ($(LINUX_DIR),)
+LINUX_DIR:=$(ARMADEUS_KERNEL_DIR)
+endif
+PWD:= $(shell pwd)
+
+default:
+ echo "Your Linux source dir is: $(LINUX_DIR)"
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) zImage modules
+
+clean:
+ echo "Your Linux source dir is: $(LINUX_DIR)"
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) clean
+
+install:
+ echo "Installing Armadeus drivers..."
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) INSTALL_MOD_PATH=$(TARGET_DIR) modules_install
+
+endif
+
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Kconfig 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,9 @@
+#
+
+#
+config ARMADEUS_FPGA_TOOL_DRIVER
+ tristate "Armadeus FPGA configuration driver"
+ default n
+ depends on ARMADEUS_FPGA_TEST
+ ---help---
+
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/Makefile 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,36 @@
+#
+# Makefile for the Armadeus FPGA loader driver
+# PATH=$HOME/nico/test/buildroot/build_arm_nofpu/staging_dir/bin:$PATH
+# make ARCH=arm
+# tftp -gr fpgaloader.ko -l /lib/modules/drivers/fpgaloader.ko 192.168.0.3
+# tftp -gr fpga_test.bit 192.168.0.3
+# insmod /lib/modules/drivers/fpgaloader.ko
+# dd if=fpga_test.bit of=/dev/fpga/loader
+
+
+BASE_DIR="../../../../buildroot/"
+
+REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+ sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+
+ARMADEUS_KERNEL_DIR=$(BASE_DIR)build_arm_nofpu/linux-$(REL)
+
+ifneq ($(KERNELRELEASE),)
+
+obj-$(CONFIG_ARMADEUS_FPGA_TOOL_DRIVER) += fpgaloader.o
+fpgaloader-objs := target-fpga-loader.o xilinx-fpga-loader.o fpga-loader.o
+
+else
+KDIR := $(ARMADEUS_KERNEL_DIR)
+PWD := $(shell pwd)
+
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+
+clean:
+ rm -f *.*o \
+ rm -f Module.symvers
+
+
+endif
+
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.c (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.c 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,284 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2006 Armadeus project
+ * Julien Boibessot <jul...@ar...>
+ * Nicolas Colombain <nic...@ar...>
+ * Generic Xilinx FPGA loader
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+#include <linux/version.h>
+#include "fpga-loader.h"
+#include "xilinx-fpga-loader.h"
+#include <asm/arch/imx-regs.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+//static unsigned long init_map;
+struct semaphore fpga_sema;
+
+/* global variables */
+static int fpga_major = FPGA_MAJOR;
+Xilinx_desc* g_current_desc = NULL;
+
+static unsigned char fpga_descriptor = 0; // use default target_fpga_desc
+module_param( fpga_descriptor, byte, 0 );
+
+#define FPGA_BUFFER_SIZE 4096
+static unsigned char g_buffer[FPGA_BUFFER_SIZE];
+static unsigned char g_nb_users = 0;
+
+
+void __exit armadeus_fpga_cleanup(void);
+
+
+//------------------------------------------------
+//
+// Handles write() done on /dev/fpgaxx
+//
+static ssize_t armadeus_fpga_write(struct file *file, const char* pData, size_t count, loff_t *f_pos)
+{
+ ssize_t ret = 0;
+
+ // Get exclusive access
+ if (down_interruptible(&fpga_sema))
+ return -ERESTARTSYS;
+
+ if( count > FPGA_BUFFER_SIZE ) {
+ count = FPGA_BUFFER_SIZE;
+ }
+
+ // Get value to write from user space
+ ret = __copy_from_user( g_buffer, pData, count);
+ if (ret != 0) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret = xilinx_load( g_current_desc, g_buffer, count );
+
+out:
+ // Release exclusive access
+ up(&fpga_sema);
+
+ return( ret );
+}
+
+static int armadeus_fpga_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ // Only one access at a time is permitted
+ if( g_nb_users > 0 )
+ return( -EBUSY );
+
+ g_nb_users++;
+ ret = xilinx_init_load( g_current_desc );
+
+ PRINTF("Opening /dev/fpga/loader%d file, %d %d\n", MINOR(inode->i_rdev), fpga_descriptor, ret);
+ return ret;
+}
+
+static int armadeus_fpga_release(struct inode *inode, struct file *file)
+{
+ if( g_nb_users > 0 )
+ g_nb_users--;
+
+ PRINTF("Closing access to /dev/fpga/loader%d\n", MINOR(inode->i_rdev));
+ return 0;
+}
+
+//------------------------------------------------
+// PROC file
+//
+static int procfile_fpga_read( char *buffer, __attribute__ ((unused)) char **start, off_t offset, int buffer_length, int *eof, __attribute__ ((unused)) void* data)
+{
+ int ret;
+
+ // We give all of our information in one go, so if the user asks us if we have more information the answer should always be no.
+ // This is important because the standard read function from the library would continue to issue the read system call until
+ // the kernel replies that it has no more information, or until its buffer is filled.
+ if( offset > 0 ) {
+ /* we have finished to read, return 0 */
+ ret = 0;
+ } else {
+ if ( data == NULL ){
+ ret = xilinx_get_descriptor_info( -1, buffer );
+ }
+ else {
+ ret = xilinx_get_descriptor_info( *((unsigned char*)data), buffer );
+ }
+ }
+
+ return ret;
+}
+
+
+static int procfile_fpga_write( __attribute__ ((unused)) struct file *file, const char *buf, unsigned long count, void *data)
+{
+ return count;
+}
+
+//------------------------------------------------
+// Handling of IOCTL calls
+//
+int armadeus_fpga_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg )
+{
+ int err = 0; int ret = 0;
+ unsigned int minor;
+
+ PRINTF( DRIVER_NAME " ## IOCTL received: (0x%x) ##\n", cmd );
+
+ // Extract the type and number bitfields, and don't decode wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
+ if (_IOC_TYPE(cmd) != FPGA_IOCTL) return -ENOTTY;
+
+ // The direction is a bitmask, and VERIFY_WRITE catches R/W transfers. `Type' is user-oriented, while access_ok is kernel-oriented,
+ // so the concept of "read" and "write" is reversed
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
+
+ if (err) return -EFAULT;
+
+ // Obtain exclusive access
+ if (down_interruptible(&fpga_sema))
+ return -ERESTARTSYS;
+ // Extract and test minor
+ minor = MINOR(inode->i_rdev);
+ if( minor > FPGA_MAX_MINOR ) {
+ printk("Minor outside range: %d !\n", minor);
+ return -EFAULT;
+ }
+
+ switch(cmd)
+ {
+ default:
+ return -ENOTTY;
+ break;
+ }
+ // Release exclusive access
+ up(&fpga_sema);
+
+ return ret;
+}
+
+//
+// Create /proc entries for direct access (with echo/cat) to GPIOs config
+//
+static int createProcEntries( void )
+{
+ static struct proc_dir_entry *fpga_Proc_File;
+
+ // Create main directory
+ proc_mkdir(FPGA_PROC_DIRNAME, NULL);
+ // Create proc file to handle GPIO values
+ fpga_Proc_File = create_proc_entry( FPGA_PROC_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL );
+
+ if( fpga_Proc_File == NULL )
+ {
+ printk(FPGA_DRIVER_NAME ": Could not register a" FPGA_PROC_FILENAME ". Terminating\n");
+ armadeus_fpga_cleanup();
+ return -ENOMEM;
+ }
+ else
+ {
+ fpga_Proc_File->read_proc = procfile_fpga_read;
+ fpga_Proc_File->write_proc = procfile_fpga_write;
+ }
+
+ return(0);
+}
+
+static struct file_operations fpga_fops = {
+ .owner = THIS_MODULE,
+ .write = armadeus_fpga_write,
+// .read = armadeus_fpga_read,
+ .open = armadeus_fpga_open,
+ .release = armadeus_fpga_release,
+ .ioctl = armadeus_fpga_ioctl,
+};
+
+//
+// Module's initialization function
+//
+int __init armadeus_fpga_init(void)
+{
+ static int result;
+
+ // Register the driver by getting a major number
+ result = register_chrdev(fpga_major, FPGA_DRIVER_NAME, &fpga_fops);
+ if (result < 0)
+ {
+ printk(KERN_WARNING FPGA_DRIVER_NAME ": can't get major %d\n", fpga_major);
+ return result;
+ }
+ if( fpga_major == 0 ) fpga_major = result; // dynamic Major allocation
+
+ // Creating /proc entries
+ result = createProcEntries();
+ if( result < 0 ) return( result );
+
+ // Initialise FPGA semaphore
+ sema_init(&fpga_sema, 1);
+
+ // initialize the current fpga descriptor with the one by default
+ g_current_desc = xilinx_get_descriptor(fpga_descriptor);
+ if( g_current_desc == NULL ){
+ return -EINVAL;
+ }
+
+ printk(FPGA_DRIVER_NAME " module " FPGA_DRIVER_VERSION " successfully loaded !\n");
+ return(0);
+}
+
+//
+// Module's cleanup function
+//
+void __exit armadeus_fpga_cleanup(void)
+{
+ PRINTF("Removing " FPGA_DRIVER_NAME " module: ");
+
+ // Remove /proc entries
+ remove_proc_entry(FPGA_PROC_FILENAME, NULL);
+ // De-register /dev interface
+ unregister_chrdev(fpga_major, FPGA_DRIVER_NAME);
+
+ PRINTF("Ok !\n ");
+}
+
+//------------------------------------------------
+
+module_init(armadeus_fpga_init);
+module_exit(armadeus_fpga_cleanup);
+
+MODULE_AUTHOR("JB / NC");
+MODULE_DESCRIPTION("Armadeus fpga's loading driver");
+MODULE_LICENSE("GPL");
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.h
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.h (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpga-loader.h 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,40 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2006 Armadeus project
+ * Julien Boibessot <jul...@ar...>
+ * Nicolas Colombain <nic...@ar...>
+ * Generic Xilinx FPGA loader
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+
+#ifndef __FPGA_LOADER_H__
+#define __FPGA_LOADER_H__
+
+#define FPGA_PROC_DIRNAME "driver/fpga"
+#define FPGA_PROC_FILENAME FPGA_PROC_DIRNAME "/loader"
+
+#define FPGA_DRIVER_VERSION "v0.0.6"
+#define FPGA_DRIVER_NAME "fpgaloader"
+
+// By default, we use dynamic allocation of major numbers
+#define FPGA_MAJOR 0
+#define FPGA_MAX_MINOR 254
+
+#define FPGA_IOCTL 0x10000000 // !! TO BE BETTER DEFINED !!
+
+#endif // __FPGA_LOADER_H__
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpgaloader.sh
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpgaloader.sh (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/fpgaloader.sh 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,11 @@
+#!/bin/sh
+# Load FPGA main module
+modprobe fpgaloader fpga_descriptor=0
+
+FPGA_MAJOR=`cat /proc/devices | grep fpgaloader | cut -d " " -f 1`
+mkdir -p /dev/fpga
+
+# For general usage
+if [ ! -e /dev/fpga/fpgaloader ] ; then
+ mknod /dev/fpga/fpgaloader c $FPGA_MAJOR 0
+fi
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.c (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.c 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,116 @@
+/*
+ **********************************************************************
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+
+ (c) Copyright 2006 Armadeus project
+ Eric Jarrige <eri...@ar...>
+ Nicolas Colombain <nic...@ar...>
+ Target Xilinx FPGA support
+*/
+
+#include "target-fpga-loader.h"
+#include "xilinx-fpga-loader.h"
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+#define GPIO_PORT(x) ((x >> 5) & 3)
+#define GPIO_SET(x) (DR(GPIO_PORT(x)) |= (1<<(x & GPIO_PIN_MASK)))
+#define GPIO_CLEAR(x) (DR(GPIO_PORT(x)) &= ~(1<<(x & GPIO_PIN_MASK)))
+#define GPIO_WRITE(x,y) ( y ? GPIO_SET(x) : GPIO_CLEAR(x) )
+#define GPIO_READ(x) ((SSR (GPIO_PORT(x)) & (1<<(x & GPIO_PIN_MASK))))
+
+/*
+ * Set the FPGA's active-low program line to the specified level
+ */
+int fpga_pgm_fn( int assert )
+{
+ GPIO_WRITE( FPGA_PROGRAM, !assert);
+ return assert;
+}
+
+/*
+ * Set the FPGA's active-high clock line to the specified level
+ */
+int fpga_clk_fn( int assert_clk )
+{
+ GPIO_WRITE( FPGA_CLOCK, assert_clk);
+ return assert_clk;
+}
+
+/*
+ * Test the state of the active-low FPGA INIT line. Return 1 on INIT
+ * asserted (low).
+ */
+int fpga_init_fn( void )
+{
+ return(!GPIO_READ(FPGA_INIT));
+}
+
+/*
+ * Test the state of the active-high FPGA DONE pin
+ */
+int fpga_done_fn( void )
+{
+ return(GPIO_READ(FPGA_DONE));
+}
+
+/*
+ * Set the FPGA's data line to the specified level
+ */
+int fpga_wr_fn( int assert_write )
+{
+ GPIO_WRITE( FPGA_DIN, assert_write);
+ return assert_write;
+}
+
+int fpga_pre_fn( void )
+{
+ // Initialize GPIO pins
+ imx_gpio_mode (FPGA_INIT | GPIO_GIUS | GPIO_DR | GPIO_IN );
+ imx_gpio_mode (FPGA_DONE | GPIO_GIUS | GPIO_DR | GPIO_IN );
+ imx_gpio_mode (FPGA_DIN | GPIO_GIUS | GPIO_DR | GPIO_OUT );
+ imx_gpio_mode (FPGA_PROGRAM | GPIO_GIUS | GPIO_DR | GPIO_OUT );
+ imx_gpio_mode (FPGA_CLOCK | GPIO_GIUS | GPIO_DR | GPIO_OUT );
+ return 1;
+}
+
+
+Xilinx_Spartan_Slave_Serial_fns fpga_fns = {
+ fpga_pre_fn,
+ fpga_pgm_fn,
+ fpga_clk_fn,
+ fpga_init_fn,
+ fpga_done_fn,
+ fpga_wr_fn,
+};
+
+Xilinx_desc target_fpga_desc[NB_TARGET_DESC] = {
+
+ { // first supported configuration (default)
+ Xilinx_Spartan,
+ slave_serial,
+ XILINX_XC3S200_SIZE,
+ (void *) &fpga_fns
+ },
+
+ { // second one
+ Xilinx_Spartan,
+ slave_serial,
+ XILINX_XC3S400_SIZE,
+ (void *) &fpga_fns
+ }
+};
+
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.h
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.h (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/target-fpga-loader.h 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,40 @@
+/*
+ **********************************************************************
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+
+ (c) Copyright 2006 Armadeus project
+ Eric Jarrige <eri...@ar...>
+ Nicolas Colombain <nic...@ar...>
+ Target Xilinx FPGA support
+
+*/
+#ifndef __TARGET_FPGA_LOADER_H__
+#define __TARGET_FPGA_LOADER_H__
+
+
+#include "xilinx-fpga-loader.h"
+#include <asm/arch/imx-regs.h>
+#include <asm/io.h>
+
+#define FPGA_INIT (GPIO_PORTB | 15) /* FPGA init pin (SSI input) */
+#define FPGA_DONE (GPIO_PORTB | 16) /* FPGA done pin (SSI input) */
+#define FPGA_DIN (GPIO_PORTB | 17) /* FPGA data pin (SSI output) */
+#define FPGA_PROGRAM (GPIO_PORTB | 18) /* FPGA prog pin (SSI output) */
+#define FPGA_CLOCK (GPIO_PORTB | 19) /* FPGA clk pin (SSI output) */
+
+#define NB_TARGET_DESC 2
+
+#endif // __TARGET_FPGA_LOADER_H__
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.c (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.c 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,277 @@
+/*
+ * (c) Copyright 2006 Armadeus project
+ * Nicolas Colombain <nic...@ar...>
+ * Xilinx FPGA support
+ *
+ * Based on the implementation(uBoot) of:
+ * Rich Ireland, Enterasys Networks, rir...@en....
+ * Keith Outwater, kei...@mv...
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include "xilinx-fpga-loader.h"
+#include "target-fpga-loader.h"
+#include <asm/arch/imx-regs.h>
+#include <asm/io.h>
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
+#define CONFIG_FPGA_DELAY()
+#define CFG_FPGA_WAIT 4000 // uS
+
+size_t bytecount = 0; // total bytes received
+extern Xilinx_desc target_fpga_desc[]; // target descriptor table
+
+/*
+ * Timeout function
+ */
+static unsigned long get_timer(unsigned long initTime)
+{
+ struct timeval tv;
+ do_gettimeofday(&tv);
+ if( tv.tv_usec > initTime ) // avoid overflow pb
+ return tv.tv_usec - initTime;
+ else
+ return initTime - tv.tv_usec;
+}
+
+/*
+ * dump the given descriptor infos
+ */
+static int xilinx_dump_descriptor_info( Xilinx_desc *desc, char* buffer )
+{
+ int len;
+ len = sprintf( buffer, "%s %s %u\n",
+ (desc->family == Xilinx_Spartan) ? "spartan":"unknown",
+ (desc->iface == slave_serial) ? "slave serial":"unknown",
+ desc->size );
+ return len;
+}
+
+/**
+ * program the FPGA.
+ * return 0 if success, >0 while programming, <0 if error detected
+ */
+static size_t spartan_serial_load (Xilinx_desc *desc, const char* buf, size_t bsize)
+{
+ Xilinx_Spartan_Slave_Serial_fns *fn = desc->iface_fns;
+ if (fn) {
+ unsigned long ts; /* timestamp */
+
+ /* Load the data */
+ if( bytecount<=desc->size ) {
+ int i;
+ unsigned char val;
+ size_t nbbyte = 0; // init local counter
+
+ while (nbbyte < bsize) {
+
+ /* Xilinx detects an error if INIT goes low (active)
+ while DONE is low (inactive) */
+ if ((*fn->done)() == 0 && (*fn->init)()) {
+ PRINTF ("** CRC error during FPGA load.\n");
+ return -ETIMEDOUT;
+ }
+ val = buf[nbbyte ++];
+ bytecount++;
+ i = 8;
+ do {
+ /* Deassert the clock */
+ (*fn->clk)(0);
+ CONFIG_FPGA_DELAY ();
+ /* Write data */
+ (*fn->wr)(val & 0x80);
+ CONFIG_FPGA_DELAY ();
+ /* Assert the clock */
+ (*fn->clk)(1);
+ CONFIG_FPGA_DELAY ();
+ val <<= 1;
+ i --;
+ } while (i > 0);
+ }
+ }
+ if( bytecount>=desc->size )
+ {
+ CONFIG_FPGA_DELAY ();
+
+ /* now check for done signal */
+ ts = get_timer(0); /* get current time */
+ (*fn->wr)(1);
+
+ while (! (*fn->done)()) {
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk)(0); /* Deassert the clock pin */
+ CONFIG_FPGA_DELAY ();
+ (*fn->clk)(1); /* Assert the clock pin */
+
+ if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
+ PRINTF ("** Timeout waiting for DONE.\n");
+ return -ETIMEDOUT;
+ }
+ }
+ }
+ return bsize;
+ }
+ return -EINVAL;
+}
+
+/**
+ * initialize the FPGA programming interface.
+ * return 0 if success, <0 if error detected
+ */
+static int spartan_serial_init (Xilinx_desc *desc)
+{
+ Xilinx_Spartan_Slave_Serial_fns *fn = desc->iface_fns;
+ if (fn) {
+ unsigned long ts; /* timestamp */
+
+ if(*fn->pre){
+ (*fn->pre)(); //Run the pre configuration function if there is one.
+ }
+
+ /* Establish the initial state */
+ (*fn->pgm)(1); /* Assert the program, commit */
+
+ /* Wait for INIT state (init low) */
+ ts = get_timer(0); /* get current time */
+ do {
+ CONFIG_FPGA_DELAY ();
+ if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
+ PRINTF ("** Timeout waiting for INIT to start.\n");
+ return -ETIMEDOUT;
+ }
+ } while (!(*fn->init)());
+
+ /* Get ready for the burn */
+ CONFIG_FPGA_DELAY ();
+ (*fn->pgm)(0); /* Deassert the program, commit */
+
+ ts = get_timer(0); /* get current time */
+ /* Now wait for INIT to go high */
+ do {
+ CONFIG_FPGA_DELAY ();
+ if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */
+ PRINTF ("** Timeout waiting for INIT to clear.\n");
+ return -ETIMEDOUT;
+ }
+ } while ((*fn->init)());
+
+ bytecount = 0; // reset byte count
+ return 0; // success
+ }
+ return -EINVAL;
+}
+
+/**
+ * program the FPGA.
+ * return 0 if success, >0 while programming, <0 if error detected
+ */
+size_t xilinx_load( Xilinx_desc *desc, const char *buf, size_t bsize )
+{
+ int ret = 0;
+
+ if( desc ) {
+ switch( desc->family ) // check family
+ {
+ case Xilinx_Spartan:
+ {
+ switch( desc->iface ) // check donwload hardware interface
+ {
+ case slave_serial: ret = spartan_serial_load( desc, buf, bsize ); break;
+ default: PRINTF("interface not supported!\n"); ret = -ENOSYS; break;
+ }
+ }
+ break;
+ default: PRINTF("family not supported!\n"); ret = -ENOSYS; break;
+ }
+ }
+ else {
+ PRINTF("invalid FPGA descriptor!\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+/**
+ * initialize the FPGA programming interface.
+ * return 0 if success, <0 if error detected
+ */
+int xilinx_init_load( Xilinx_desc *desc )
+{
+ int ret = 0;
+
+ if( desc ) {
+ switch( desc->family ) // check family
+ {
+ case Xilinx_Spartan:
+ {
+ switch( desc->iface ) // check donwload hardware interface
+ {
+ case slave_serial: ret = spartan_serial_init( desc ); break;
+ default: PRINTF("interface not supported!\n"); ret = -ENOSYS; break;
+ }
+ }
+ break;
+ default: PRINTF("family not supported!\n"); ret = -ENOSYS; break;
+ }
+ }
+ else {
+ PRINTF("invalid FPGA descriptor!\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+/**
+ * get the descriptor corresponding to desc_id
+ * return NULL if error
+ */
+Xilinx_desc * xilinx_get_descriptor( unsigned char desc_id )
+{
+ if( desc_id < NB_TARGET_DESC ){
+ return &(target_fpga_desc[desc_id]);
+ }
+ return NULL;
+}
+
+/**
+ * get the descriptor infos
+ */
+int xilinx_get_descriptor_info( int desc_id, char* buffer )
+{
+ int len = 0;
+
+ if( desc_id >= 0 ) {
+ len = xilinx_dump_descriptor_info( &target_fpga_desc[desc_id], buffer );
+ }
+ else { // all desc requested
+ unsigned char i;
+ for( i=0; i<NB_TARGET_DESC; i++ ) {
+ len += xilinx_dump_descriptor_info( &target_fpga_desc[i], buffer+len );
+ }
+ }
+
+ return len;
+}
+
+
+
Added: trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.h
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.h (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpga_devtools/xilinx-fpga-loader.h 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,117 @@
+/*
+ * (c) Copyright 2006 Armadeus project
+ * Nicolas Colombain <nic...@ar...>
+ * Xilinx FPGA support
+ *
+ * Based on the implementation(uBoot) of:
+ * Rich Ireland, Enterasys Networks, rir...@en....
+ * Keith Outwater, kei...@mv...
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+#ifndef __XILINX_FPGA_H__
+#define __XILINX_FPGA_H__
+
+#include <linux/types.h>
+
+//#define FPGA_DEBUG
+#undef FPGA_DEBUG
+
+#ifdef FPGA_DEBUG
+#define PRINTF(fmt,args...) printk (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+
+
+/* Spartan-III */
+#define XILINX_XC3S50_SIZE 439264/8
+#define XILINX_XC3S200_SIZE 1047616/8
+#define XILINX_XC3S400_SIZE 1699136/8
+#define XILINX_XC3S1000_SIZE 3223488/8
+#define XILINX_XC3S1500_SIZE 5214784/8
+#define XILINX_XC3S2000_SIZE 7673024/8
+#define XILINX_XC3S4000_SIZE 11316864/8
+#define XILINX_XC3S5000_SIZE 13271936/8
+
+
+typedef enum { /* typedef Xilinx_iface */
+ min_xilinx_iface_type, /* low range check value */
+ slave_serial, /* serial data and external clock */
+ max_xilinx_iface_type /* insert all new types before this */
+} Xilinx_iface; /* end, typedef Xilinx_iface */
+
+typedef enum { /* typedef Xilinx_Family */
+ min_xilinx_type, /* low range check value */
+ Xilinx_Spartan, /* Spartan-II Family */
+ max_xilinx_type /* insert all new types before this */
+} Xilinx_Family; /* end, typedef Xilinx_Family */
+
+typedef struct { /* typedef Xilinx_desc */
+ Xilinx_Family family; /* part type */
+ Xilinx_iface iface; /* interface type */
+ size_t size; /* bytes of data part can accept */
+ void * iface_fns; /* interface function table */
+} Xilinx_desc; /* end, typedef Xilinx_desc */
+
+
+/** pointer to target specific low level function */
+typedef int (*Xilinx_pgm_fn)( int assert_pgm );
+typedef int (*Xilinx_init_fn)(void);
+typedef int (*Xilinx_done_fn)(void);
+typedef int (*Xilinx_clk_fn)( int assert_clk );
+typedef int (*Xilinx_wr_fn)( int assert_write );
+typedef int (*Xilinx_pre_fn)(void);
+
+/** struct of target specific low level functions */
+typedef struct {
+ Xilinx_pre_fn pre;
+ Xilinx_pgm_fn pgm;
+ Xilinx_clk_fn clk;
+ Xilinx_init_fn init;
+ Xilinx_done_fn done;
+ Xilinx_wr_fn wr;
+} Xilinx_Spartan_Slave_Serial_fns;
+
+/**
+ * program the FPGA.
+ * return 0 if success, >0 while programming, <0 if error detected
+ */
+size_t xilinx_load( Xilinx_desc *desc, const char *buf, size_t bsize );
+
+/**
+ * initialize the FPGA programming interface.
+ * return 0 if success, <0 if error detected
+ */
+int xilinx_init_load( Xilinx_desc *desc );
+
+/**
+ * get the descriptor infos, return the number of char placed in the buffer
+ */
+int xilinx_get_descriptor_info( int desc_id, char* buffer);
+
+/**
+ * get the descriptor corresponding to desc_id
+ * return NULL if error
+ */
+Xilinx_desc * xilinx_get_descriptor( unsigned char desc_id );
+
+#endif // __XILINX_FPGA_H__
Added: trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/.tmp_versions/fpgaaccess.mod
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/.tmp_versions/fpgaaccess.mod (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/.tmp_versions/fpgaaccess.mod 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,2 @@
+/home/fabien/armadeus/target/linux/modules/fpga/fpgaaccess/fpgaaccess.ko
+/home/fabien/armadeus/target/linux/modules/fpga/fpgaaccess/fpgaaccess.o
Added: trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Kconfig 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,8 @@
+#
+#
+
+config ARMADEUS_FPGAACCESS_DRIVER
+ tristate "fpgaaccess driver"
+ default n
+ depends on ARMADEUS_FPGA_TEST
+ ---help---
Added: trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Makefile 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,34 @@
+#
+# Makefile for the Armadeus Wb_led drivers
+#
+
+BASE_DIR="../../../../../buildroot/"
+
+REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+ sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+
+ARMADEUS_KERNEL_DIR=$(BASE_DIR)build_arm/linux-$(REL)
+
+ifneq ($(KERNELRELEASE),)
+
+obj-$(CONFIG_ARMADEUS_FPGAACCESS_DRIVER) += fpgaaccess.o
+
+# Part executed when called from standard make in this directory:
+# (preferably use Makefile in parent directory)
+
+else
+KDIR := $(ARMADEUS_KERNEL_DIR)
+PWD := $(shell pwd)
+
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+
+fpgaregs: fpgaregs.c
+ $(BASE_DIR)build_arm/staging_dir/bin/arm-linux-gcc -Wall fpgaregs.c -o fpgaregs
+
+clean:
+ rm -f *.*o \
+ rm -f Module.symvers
+
+endif
+
Property changes on: trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaaccess.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaaccess.c (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaaccess.c 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,178 @@
+/*
+ ***********************************************************************
+ * fpgaaccess.c
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ *
+ * A simple driver for reading and writing on
+ * fpga throught a character file /dev/fpgaaccess
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+
+#include "fpgaaccess.h"
+
+/*************************************/
+/* to read write fpgaaccess register */
+/*************************************/
+ssize_t fpgaaccess_read(struct file *fildes, char __user *buff,
+ size_t count, loff_t *offp){
+ struct fpgaaccess_dev *sdev = fildes->private_data;
+ u32 data=0;
+
+ if(*offp >= FPGA_SIZE || ((*offp)%2 != 0)){ /* offset must be pair */
+ return 0;
+ }
+
+ if(count > 4) /* 32bits max*/
+ count = 4;
+
+ if (count == 2)
+ data = ioread16(sdev->fpga_virtual_base_address + *offp);
+ else
+ data = ioread32(sdev->fpga_virtual_base_address + *offp);
+
+ /* return data for user */
+ if(copy_to_user(buff,&data,count)){
+ printk(KERN_WARNING "read : copy to user data error\n");
+ return -EFAULT;
+ }
+ return 0;
+}
+
+ssize_t fpgaaccess_write(struct file *fildes, const char __user *
+ buff,size_t count, loff_t *offp){
+ struct fpgaaccess_dev *sdev = fildes->private_data;
+ u32 data=0;
+
+ if(*offp >= FPGA_SIZE || ((*offp)%2 != 0)){ /* offset must be pair */
+ return 0;
+ }
+
+ if(count > 4) /* 32 bits max)*/
+ count = 4;
+
+ if(copy_from_user(&data,buff,count)){
+ printk(KERN_WARNING "write : copy from user error\n");
+ return -EFAULT;
+ }
+
+ if (count == 2)
+ iowrite16(data,sdev->fpga_virtual_base_address + *offp);
+ else
+ iowrite32(data,sdev->fpga_virtual_base_address + *offp);
+
+ return count;
+}
+
+int fpgaaccess_open(struct inode *inode, struct file *filp){
+ filp->private_data=container_of(inode->i_cdev,struct fpgaaccess_dev,cdev);
+ return 0;
+}
+
+int fpgaaccess_release(struct inode *inode, struct file *filp){
+ filp->private_data=NULL;
+ return 0;
+}
+
+
+
+/********************************/
+/* init and release module */
+/********************************/
+
+static int __init fpgaaccess_init(void){
+ int result;
+ int fpgaaccess_major,fpgaaccess_minor;
+ struct fpgaaccess_dev *sdev;
+
+ fpgaaccess_major = 250;
+ fpgaaccess_minor = 0;
+
+ /* Allocate a private structure and reference it as driver's data */
+ PDEBUG("Allocate a private structure and reference it as driver s data\n");
+ sdev = (struct fpgaaccess_dev *)kmalloc(sizeof(struct fpgaaccess_dev),GFP_KERNEL);
+ if(sdev == NULL){
+ printk(KERN_WARNING "FPGAACCESS: unable to allocate private structure\n");
+ return -ENOMEM;
+ }
+
+ fpgaaccessdev = sdev;
+
+ /* Get the major and minor device numbers */
+ PDEBUG("Get the major and minor device numbers\n");
+ if(fpgaaccess_major){
+ devno = MKDEV(fpgaaccess_major,fpgaaccess_minor);
+ result = register_chrdev_region(devno, N_DEV,FPGAACCESS_NAME);
+ }else{
+ result = alloc_chrdev_region(&devno,fpgaaccess_minor,N_DEV,FPGAACCESS_NAME);
+ fpgaaccess_major = MAJOR(devno);
+ }
+ printk(KERN_INFO "fpgaaccess: MAJOR: %d MINOR: %d\n",MAJOR(devno),MINOR(devno));
+ if(result < 0){
+ printk(KERN_ERR "fpgaaccess: can't get major %d\n",fpgaaccess_major);
+ goto mkdev_error;
+ }
+
+ /* Init the cdev structure */
+ PDEBUG("Init the cdev structure\n");
+ cdev_init(&sdev->cdev,&fpgaaccess_fops);
+ sdev->cdev.owner = THIS_MODULE;
+
+ /* Add the device to the kernel, connecting cdev to major/minor number */
+ PDEBUG("Add the device to the kernel, connecting cdev to major/minor number \n");
+ result = cdev_add(&sdev->cdev,devno,1);
+ if(result < 0){
+ printk(KERN_WARNING "FPGAACCESS: can't add cdev\n");
+ goto cdevadd_error;
+ }
+
+ sdev->fpga_virtual_base_address = (void*)FPGA_BASE_ADDR;
+
+ /* ok module insered */
+ fpgaaccessdev=sdev;
+ printk(KERN_INFO "FPGAACCESS module insered\n");
+ return 0;
+
+cdevadd_error:
+ /* free major and minor number */
+ unregister_chrdev_region(devno,N_DEV);
+ printk(KERN_INFO "fpgaaccess module deleted\n");
+mkdev_error:
+ printk(KERN_ERR "%s: not insered\n",FPGAACCESS_NAME);
+ kfree(sdev);
+ return result;
+
+}
+
+static void __exit fpgaaccess_exit(void){
+ struct fpgaaccess_dev *sdev;
+
+ sdev = fpgaaccessdev;
+
+ /* delete the cdev structure */
+ cdev_del(&sdev->cdev);
+
+ /* free major and minor number */
+ unregister_chrdev_region(devno,N_DEV);
+ printk(KERN_INFO "fpgaaccess module deleted\n");
+
+ /* freed structure device */
+ kfree(sdev);
+}
+
+
Added: trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaaccess.h
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaaccess.h (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaaccess.h 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,121 @@
+/*
+ ***********************************************************************
+ * fpgaaccess.h
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ *
+ * A simple driver for reading and writing on
+ * fpga throught a character file /dev/fpgaaccess
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+
+#ifndef __FPGAACCESS_H_
+#define __FPGAACCESS_H_
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+
+/* form module/drivers */
+#include <linux/init.h>
+#include <linux/module.h>
+
+/* for file operations */
+#include <linux/fs.h>
+#include <linux/cdev.h>
+
+/* copy_to_user function */
+#include <asm/uaccess.h>
+
+/* readw() writew() */
+#include <asm/io.h>
+
+/* hardware addresses */
+#include <asm/hardware.h>
+
+#endif
+
+/* for debugging messages*/
+#define FPGAACCESS_DEBUG
+
+#undef PDEBUG
+#ifdef FPGAACCESS
+# ifdef __KERNEL__
+ /* for kernel spage */
+# define PDEBUG(fmt,args...) printk(KERN_DEBUG "fpgaaccess : " fmt, ##args)
+# else
+ /* for user space */
+# define PDEBUG(fmt,args...) printk(stderr, fmt, ##args)
+# endif
+#else
+# define PDEBUG(fmt,args...) /* no debbuging message */
+#endif
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabien Marteau <fab...@ar...> - ARMadeus Systems");
+MODULE_DESCRIPTION("FPGA access device driver");
+
+/* some defines */
+
+#define FPGAACCESS_NAME "fpgaaccess"
+#define FPGA_BASE_ADDR IMX_CS1_VIRT
+#define FPGA_SIZE IMX_CS1_SIZE
+#define N_DEV 1
+
+
+/*************************/
+/* main device structures */
+/*************************/
+struct fpgaaccess_dev{
+ struct cdev cdev; /* Char device structure */
+ void * fpga_virtual_base_address; /* fpga register base address*/
+};
+
+static dev_t devno;
+struct fpgaaccess_dev *fpgaaccessdev;
+
+/*************************************/
+/* to read write fpgaaccess register */
+/*************************************/
+ssize_t fpgaaccess_read(struct file *fildes, char __user *buff,
+ size_t count, loff_t *offp);
+
+ssize_t fpgaaccess_write(struct file *fildes, const char __user *
+ buff,size_t count, loff_t *offp);
+int fpgaaccess_open(struct inode *inode, struct file *filp);
+
+int fpgaaccess_release(struct inode *, struct file *filp);
+
+struct file_operations fpgaaccess_fops = {
+ .owner = THIS_MODULE,
+ .read = fpgaaccess_read,
+ .write = fpgaaccess_write,
+ .open = fpgaaccess_open,
+ .release = fpgaaccess_release,
+};
+
+/********************************/
+/* init and release module */
+/********************************/
+
+static int __init fpgaaccess_init(void);
+static void __exit fpgaaccess_exit(void);
+
+module_init(fpgaaccess_init);
+module_exit(fpgaaccess_exit);
Property changes on: trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaregs
___________________________________________________________________
Added: svn:executable
+ *
Added: svn:mime-type
+ application/octet-stream
Added: trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaregs.c
===================================================================
--- trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaregs.c (rev 0)
+++ trunk/target/linux/modules/fpga/dev_tools/fpgaaccess/fpgaregs.c 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,110 @@
+/************************************************************************
+ * a program to write/read 16/32bits values on fpga address map
+ * 7 april 2008
+ * fpgaregs.c
+ *
+ * (c) Copyright 2008 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ *
+ * A simple driver for reading and writing on
+ * fpga throught a character file /dev/fpgaaccess
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* file management */
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* as name said */
+#include <signal.h>
+
+/* sleep, write(), read() */
+#include <unistd.h>
+
+/* converting string */
+#include <string.h>
+
+
+#define WORD_ACCESS (2)
+#define LONG_ACCESS (4)
+
+void displayResult(char* text, unsigned int accesstype, unsigned int value, unsigned int address)
+{
+ if( accesstype == WORD_ACCESS )
+ printf("%s %04x at %08x\n",text, (unsigned short)value,address);
+ else
+ printf("%s %08x at %08x\n",text, value,address);
+}
+
+
+int main(int argc, char *argv[])
+{
+ unsigned short address;
+ unsigned int value ;
+ int retval, error = EXIT_SUCCESS;
+ int ffpga, accesstype = LONG_ACCESS;
+
+ if((argc < 3) || (argc > 4)){
+ printf("invalid arguments number\nfpgaregs [w,l] fpga_reg_add [value].\n\tw: word access, l: long access\n\
+\tEx: fpgaregs w 0x10 0x1234, fpgaregs l 0x10 0x12345678\n");
+ exit(EXIT_FAILURE);
+ }
+
+ ffpga=open("/dev/fpgaaccess",O_RDWR);
+ if(ffpga<0){
+ printf("can't open file /dev/fpgaaccess\n");
+ exit(EXIT_FAILURE);
+ }
+
+ address = (unsigned int)strtol(argv[2], (char **)NULL, 16);
+
+ if(argc<3){
+ printf("invalid command line");
+ }
+ else {
+ if( *(argv[1]) == 'w' )
+ accesstype = WORD_ACCESS;
+
+ /* write value at address */
+ if(argc == 4){
+ value = strtoul(argv[3], (char **)NULL, 16);
+ retval = pwrite(ffpga,(void *)&value,accesstype,address);
+ if(retval<0){
+ printf("write error\n");
+ error = EXIT_FAILURE;
+ }
+ else
+ displayResult("Write", accesstype, value, address);
+
+ /* read address value */
+ }else if(argc == 3){
+ retval = pread(ffpga,(void *)&value,accesstype,address);
+ if(retval<0){
+ perror("Read error\n");
+ error = EXIT_FAILURE;
+ }
+ else
+ displayResult("Read", accesstype, value, address);
+ }
+ }
+ close(ffpga);
+ exit(error);
+}
+
Added: trunk/target/linux/modules/fpga/others/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/others/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/others/Kconfig 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,17 @@
+#
+# Armadeus custom drivers configuration
+#
+#
+
+#
+config ARMADEUS_FPGA_OTHERS_DRIVERS
+ boolean "Others drivers for FPGA"
+ default n
+ depends on ARMADEUS_FPGA_DRIVERS
+ ---help---
+ All drivers for FPGA components
+
+source "drivers/armadeus/fpga/others/Wb_button/Kconfig"
+source "drivers/armadeus/fpga/others/Wb_led/Kconfig"
+source "drivers/armadeus/fpga/others/i2ctest/Kconfig"
+source "drivers/armadeus/fpga/others/ps2keyboard/Kconfig"
Added: trunk/target/linux/modules/fpga/others/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/others/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/others/Makefile 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,41 @@
+#
+# Main Makefile for the Armadeus FPGA related drivers
+#
+# Add your subdirectories to obj- target
+#
+
+ifneq ($(KERNELRELEASE),)
+
+# Part executed when called from kernel build system:
+
+obj-$(CONFIG_ARMADEUS_FPGA_OTHERS_DRIVERS) += Wb_button/ Wb_led/ i2ctest/ ps2keyboard/
+
+else
+
+# Part executed when called from standard make in this directory:
+
+BASE_DIR:=../../../../buildroot/
+REL:=$(shell grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+ sed -e 's/BR2_PACKAGE_LINUX_VERSION=//' | sed -e 's/"//g')
+#`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+# sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+ARMADEUS_KERNEL_DIR:=$(BASE_DIR)build_arm/linux-$(REL)
+ifeq ($(LINUX_DIR),)
+LINUX_DIR:=$(ARMADEUS_KERNEL_DIR)
+endif
+PWD:= $(shell pwd)
+
+default:
+ echo "Your Linux source dir is: $(LINUX_DIR)"
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) zImage modules
+
+clean:
+ echo "Your Linux source dir is: $(LINUX_DIR)"
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) clean
+
+install:
+ echo "Installing Armadeus drivers..."
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) INSTALL_MOD_PATH=$(TARGET_DIR) modules_install
+
+endif
+
Property changes on: trunk/target/linux/modules/fpga/others/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fpga/others/Wb_button/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_button/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/others/Wb_button/Kconfig 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,8 @@
+#
+#
+
+config ARMADEUS_BUTTON_DRIVER
+ tristate "Wishbone Button driver"
+ default n
+ depends on ARMADEUS_FPGA_OTHERS_DRIVERS
+ ---help---
Added: trunk/target/linux/modules/fpga/others/Wb_button/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_button/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/others/Wb_button/Makefile 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,38 @@
+#
+# Makefile for the Armadeus Wb_button drivers
+#
+
+BASE_DIR="../../../../../buildroot/"
+
+REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+ sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+
+ARMADEUS_KERNEL_DIR=$(BASE_DIR)build_arm/linux-$(REL)
+
+ifneq ($(KERNELRELEASE),)
+
+obj-$(CONFIG_ARMADEUS_BUTTON_DRIVER) += button.o
+
+# Part executed when called from standard make in this directory:
+# (preferably use Makefile in parent directory)
+
+else
+
+KDIR := $(ARMADEUS_KERNEL_DIR)
+PWD := $(shell pwd)
+
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+ -cp button.ko /tftpboot/
+
+test:
+ ~/armadeus/buildroot/build_arm/staging_dir/bin/arm-linux-gcc testbutton.c -o testbutton
+ chmod 755 testbutton
+ cp testbutton /tftpboot/
+
+clean:
+ rm -f *.*o \
+ rm -f Module.symvers
+
+endif
+
Property changes on: trunk/target/linux/modules/fpga/others/Wb_button/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fpga/others/Wb_button/button.c
===================================================================
--- trunk/target/linux/modules/fpga/others/Wb_button/button.c (rev 0)
+++ trunk/target/linux/modules/fpga/others/Wb_button/button.c 2008-08-05 15:28:22 UTC (rev 868)
@@ -0,0 +1,226 @@
+/*
+ ***********************************************************************
+ *
+ * (c) Copyright 2007 Armadeus project
+ * Fabien Marteau <fab...@ar...>
+ * Driver for Wb_button IP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ **********************************************************************
+ */
+
+#include "button.h"
+
+/*********************************
+ * simple fpga read/write
+ *********************************/
+
+
+static ssize_t button_fpga_read(void * addr,u16 *data,struct button_dev *dev){
+ *data = ioread16(addr);/* read the button value */
+ return 2;
+}
+
+
+static ssize_t button_fpga_write(void * addr,u16 *data,struct button_dev *dev){
+ ssize_t retval;
+
+ iowrite16(*data,addr);/* write the button value */
+ retval = 2;
+ return retval;
+}
+
+/**********************************
+ * irq management
+ * awake read process
+ * *****...
[truncated message content] |
Revision: 867
http://armadeus.svn.sourceforge.net/armadeus/?rev=867&view=rev
Author: FabM
Date: 2008-08-05 09:44:44 +0000 (Tue, 05 Aug 2008)
Log Message:
-----------
[Firmware] Hack kernel to export som irq handling functions.
Added Paths:
-----------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/200-hack-kernel-to-export-some-irq-handling-functions.diff
Added: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/200-hack-kernel-to-export-some-irq-handling-functions.diff
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/200-hack-kernel-to-export-some-irq-handling-functions.diff (rev 0)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/200-hack-kernel-to-export-some-irq-handling-functions.diff 2008-08-05 09:44:44 UTC (rev 867)
@@ -0,0 +1,61 @@
+COPY IT IN buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/
+--- linux-2.6.23.1/arch/arm/kernel/irq.c 2007-10-12 18:43:44.000000000 +0200
++++ linux-2.6.23.1.irq_manager/arch/arm/kernel/irq.c 2008-07-24 16:43:52.000000000 +0200
+@@ -152,6 +152,7 @@
+ desc->status &= ~IRQ_NOAUTOEN;
+ spin_unlock_irqrestore(&desc->lock, flags);
+ }
++EXPORT_SYMBOL(set_irq_flags);
+
+ void __init init_IRQ(void)
+ {
+--- linux-2.6.23.1/include/asm-arm/arch-imx/irqs.h 2008-07-29 17:26:13.000000000 +0200
++++ linux-2.6.23.1.irq_manager/include/asm-arm/arch-imx/irqs.h 2008-07-24 17:26:17.000000000 +0200
+@@ -112,6 +112,10 @@
+ /* decode irq number to use with IMR(x), ISR(x) and friends */
+ #define IRQ_TO_REG(irq) ((irq - IMX_IRQS) >> 5)
+
+-#define NR_IRQS (IRQ_GPIOD(32) + 1)
++#define IRQ_FPGA_START (IRQ_GPIOD(32) + 1)
++#define IRQ_FPGA(x) (IRQ_FPGA_START + x)
++
++//#define NR_IRQS (IRQ_GPIOD(32) + 1)
++#define NR_IRQS (IRQ_FPGA(16) + 1)
+ #define IRQ_GPIO(x)
+ #endif
+--- linux-2.6.23.1/kernel/irq/chip.c 2007-10-12 18:43:44.000000000 +0200
++++ linux-2.6.23.1.irq_manager/kernel/irq/chip.c 2008-07-24 16:47:35.000000000 +0200
+@@ -502,6 +502,7 @@
+ out_unlock:
+ spin_unlock(&desc->lock);
+ }
++EXPORT_SYMBOL(handle_edge_irq);
+
+ #ifdef CONFIG_SMP
+ /**
+@@ -581,6 +582,7 @@
+ }
+ spin_unlock_irqrestore(&desc->lock, flags);
+ }
++EXPORT_SYMBOL(__set_irq_handler);
+
+ void
+ set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
+@@ -589,6 +591,7 @@
+ set_irq_chip(irq, chip);
+ __set_irq_handler(irq, handle, 0, NULL);
+ }
++EXPORT_SYMBOL(set_irq_chip_and_handler);
+
+ void
+ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
+--- linux-2.6.23.1/kernel/irq/handle.c 2007-10-12 18:43:44.000000000 +0200
++++ linux-2.6.23.1.irq_manager/kernel/irq/handle.c 2008-07-24 17:02:07.000000000 +0200
+@@ -59,6 +59,7 @@
+ #endif
+ }
+ };
++EXPORT_SYMBOL(irq_desc);
+
+ /*
+ * What should we do if we get a hw irq event on an illegal vector?
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-08-01 16:02:55
|
Revision: 866
http://armadeus.svn.sourceforge.net/armadeus/?rev=866&view=rev
Author: artemys
Date: 2008-08-01 16:03:02 +0000 (Fri, 01 Aug 2008)
Log Message:
-----------
[LINUX] Refactoring of generic GPIO driver, for handling interrupts and pull-up, still long way to go to reach state of the art, but it's usable... ;-) Next step is to integrate JiBee's work.
Modified Paths:
--------------
trunk/target/linux/modules/gpio/Makefile
trunk/target/linux/modules/gpio/core.c
trunk/target/linux/modules/gpio/core.h
trunk/target/linux/modules/gpio/loadgpio.sh
Modified: trunk/target/linux/modules/gpio/Makefile
===================================================================
--- trunk/target/linux/modules/gpio/Makefile 2008-07-29 22:04:58 UTC (rev 865)
+++ trunk/target/linux/modules/gpio/Makefile 2008-08-01 16:03:02 UTC (rev 866)
@@ -28,6 +28,7 @@
clean:
rm -f *.*o \
rm -f Module.symvers
+ rm -f .*.cmd
endif
Modified: trunk/target/linux/modules/gpio/core.c
===================================================================
--- trunk/target/linux/modules/gpio/core.c 2008-07-29 22:04:58 UTC (rev 865)
+++ trunk/target/linux/modules/gpio/core.c 2008-08-01 16:03:02 UTC (rev 866)
@@ -1,5 +1,11 @@
/*
- **********************************************************************
+ * Armadeus i.MXL GPIO management driver
+ *
+ * Copyright (C) 2006-2008 Armadeus Project / Armadeus Systems
+ * Authors: Nicolas Colombain / Julien Boibessot
+ *
+ * Inspired by a lot of other GPIO management systems...
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -13,19 +19,20 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- **********************************************************************
+ *
*/
-
#include <asm/arch/imx-regs.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
-#include "core.h"
+#include "core.h" // TBDJUJU: put core.h contents here....
#define GPIO_PROC_FILE 1
-#define SETTINGS_PROC_FILE 4
+#define SETTINGS_PROC_FILE (1 << 3)
+#define SETTINGS_IRQ_PROC_FILE (1 << 4)
+#define SETTINGS_PULLUP_PROC_FILE (1 << 5)
#define PORT_A 0
#define PORT_B 1
@@ -34,6 +41,15 @@
#define NB_PORTS 4
#define PORT_MAX_ID 4
+#define MAX_MINOR (255) /* Linux limitation */
+
+#define FULL_PORTA_MINOR (MAX_MINOR - PORT_A)
+#define FULL_PORTB_MINOR (MAX_MINOR - PORT_B)
+#define FULL_PORTC_MINOR (MAX_MINOR - PORT_C)
+#define FULL_PORTD_MINOR (MAX_MINOR - PORT_D)
+
+#define FULL_MINOR_TO_PORT(x) (MAX_MINOR - x)
+
// Parameters order:
enum {
DDIR_I = 0,
@@ -54,10 +70,6 @@
PUEN_I,
};
-/*#define PORTB27_21MASK ((unsigned long)0x0FF00000)
-#define PORTB27_21SHIFT 20
-#define PORT_D_31_10_MASK 0xFFFFFC00*/
-
// Global variables
struct gpio_operations *driver_ops;
static int gpio_major = GPIO_MAJOR;
@@ -67,10 +79,18 @@
static unsigned long init_map;
struct semaphore gpio_sema;
-static unsigned int gPortAIndex = PORT_A;
-static unsigned int gPortBIndex = PORT_B;
-static unsigned int gPortCIndex = PORT_C;
-static unsigned int gPortDIndex = PORT_D;
+enum {
+ VALUE = 0,
+ DIRECTION,
+ PULL_UP,
+ INTERRUPT,
+};
+
+struct gpio_settings {
+ unsigned int port;
+ int type;
+};
+
// Module parameters
#define NB_CONFIG_REGS 16
static int portA_init[NB_CONFIG_REGS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -86,45 +106,75 @@
static int portD_init_nb = 0;
module_param_array( portD_init, int, &portD_init_nb, 0000 );
-// Static functions
+
+struct gpio_item {
+ spinlock_t lock;
+
+ int enabled;
+ int initialized;
+ int port;
+ int nb_pins;
+ int number;
+ u32 pin_mask;
+ u32 oe_mask;
+
+ /* Pin state last time we read it (for blocking reads) */
+ u32 pin_state;
+ int changed;
+
+ wait_queue_head_t change_wq;
+ struct fasync_struct *async_queue;
+
+ int id;
+ struct class_device *gpio_dev;
+ struct cdev char_dev;
+// struct config_item item; TBDJUJU: Use configfs filesystem !
+};
+
+static unsigned int shadows_irq[NB_PORTS] = { 0, 0, 0, 0 };
+
+
+// Static functions
static void __exit armadeus_gpio_cleanup(void);
static int toString(unsigned long value, char* buffer, int number_of_bits)
{
static int i;
-
+
/* convert it into a string */
for(i=number_of_bits;i>0;i--){
buffer[number_of_bits-i]=test_bit(i-1,&value)?'1':'0';
}
-
+
buffer[number_of_bits] = '\n';
buffer[number_of_bits+1] = 0;
-
+
return number_of_bits+1;
}
+/* Convert binary string ("010011") to int. Don't care of non '0' / '1' chars */
static unsigned long fromString(char* buffer, int number_of_bits)
{
- static int i;
- static unsigned long ret_val=0;
-
- ret_val = 0;
- /* Create WORD to write from the string */
- for(i=0;i<number_of_bits;i++)
- {
- if (buffer[i] == 0) break;
-
- if (buffer[i] == '0' || buffer[i] == '1') {
- ret_val=ret_val<<1;
- }
-
- if (buffer[i] == '1') {
- ret_val |= 1;
- }
- }
-
- return(ret_val);
+ int i, j;
+ unsigned long ret_val=0;
+
+ ret_val = 0;
+ /* Create WORD to write from the string */
+ for( i=0, j=1; j<=number_of_bits; i++)
+ {
+ //printk("%x j=%d i=%d\n", buffer[i], j, i);
+ if (buffer[i] == '\0') break; /* EOC */
+
+ if (buffer[i] == '0' || buffer[i] == '1') {
+ ret_val <<= 1;
+ if (buffer[i] == '1') {
+ ret_val |= 1;
+ }
+ j++;
+ }
+ }
+
+ return(ret_val);
}
//------------------------------------------------
@@ -132,7 +182,7 @@
// Low level functions
//
#define DEFAULT_VALUE 0x12345678
-// These masks are for restricting user acces to configuration of some criticals GPIO pins used by Armadeus and not configurable
+// These masks are for restricting user access to configuration of some criticals GPIO pins used by Armadeus and not configurable
static unsigned long MASK[]= { 0x0003FFFE, 0xF00FFF00, 0x0003E1F8, 0xFFFFFFFF };
#define PORT_A_MASK 0x0003FFFE
#define PORT_B_MASK 0xF00FFF00
@@ -237,19 +287,11 @@
initializePortB();
initializePortC();
initializePortD();
-
-/* GIUS(PORT_B) = GIUS(PORT_B) | PORTB27_21MASK; //set only portb27..21
- PUEN(PORT_B) = PUEN(PORT_B) | PORTB27_21MASK;
- OCR1(PORT_B) = OCR1(PORT_B); // nothing to do for 27..21
- OCR2(PORT_B) = OCR2(PORT_B) | 0x00FFFF00;
-*/
-/* GIUS(PORT_D) = GIUS(PORT_D) | PORT_D_31_10_MASK; //set only portD 31..10
- PUEN(PORT_D) = PUEN(PORT_D) | PORT_D_31_10_MASK;
- OCR1(PORT_D) = OCR1(PORT_D) | 0xFFFF0000;
- OCR2(PORT_D) = OCR2(PORT_D) | 0xFFFFFFFF;
-*/
}
+
+// TBDJUJU: replace the following functions with imx_gpio_xxx one !!
+
static void writeOnPort( unsigned int aPort, unsigned int aValue )
{
//
@@ -281,45 +323,42 @@
return( port_value );
}
+char* port_name[NB_PORTS] = { "PortA", "PortB", "PortC", "PortD" };
+char* port_setting_name[4] = { "Value", "Direction", "Pull-up", "Interrupt" };
//------------------------------------------------
//
// Handles write() done on /dev/gpioxx
//
-static ssize_t armadeus_gpio_write(struct file *file, const char *data, size_t count, loff_t *ppos)
+static ssize_t armadeus_gpio_dev_write(struct file *file, const char *data, size_t count, loff_t *offset)
{
- unsigned int minor=0, port_value=0, value=0;
- size_t i;
-// /*char*/unsigned int port_value=0;
- ssize_t ret = 0;
-// unsigned int value=0;
-
- minor = MINOR(file->f_dentry->d_inode->i_rdev);
- printk("armadeus_gpio_write() on minor %d\n", minor);
-
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
- if (down_interruptible(&gpio_sema))
+ unsigned int minor=0;
+ u32 value=0;
+ ssize_t ret = 0;
+ struct gpio_item *gpio = file->private_data;
+
+ minor = MINOR(file->f_dentry->d_inode->i_rdev);
+
+ printk("- %s %d byte(s) on minor %d -> %s pin %d\n", __FUNCTION__, count, minor, port_name[gpio->port], gpio->number);
+
+ if (down_interruptible(&gpio_sema)) /* Usefull ?? */
return -ERESTARTSYS;
- value = 0;
- for (i = 0; i < count; ++i)
- {
- port_value = 0;
- // Get value to write from user space
- ret = __get_user(port_value, (unsigned int*)/*(char *)*/data);
- if (ret != 0) {
- //ret = -EFAULT;
- goto out;
- }
+ count = min(count, (size_t)4);
+ if (copy_from_user(&value, data, count)) {
+ ret = -EFAULT;
+ goto out;
+ }
- writeOnPort( minor, port_value );
-
- data++;
- *ppos = *ppos+1;
- }
- ret = count;
+ if( gpio->nb_pins != 1) {
+ printk("Full port write: 0x%x\n", value);
+ writeOnPort( gpio->port, value );
+ } else {
+ value = value ? 1 : 0;
+ printk("Single pin write: %d\n", value);
+ imx_gpio_set_value( minor, value );
+ }
+ ret = count;
out:
up(&gpio_sema);
@@ -329,262 +368,182 @@
//
// Handles read() done on /dev/gpioxx
//
-static ssize_t armadeus_gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+static ssize_t armadeus_gpio_dev_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
unsigned minor = MINOR(file->f_dentry->d_inode->i_rdev);
- unsigned long value=0;
- size_t bytes_read=0;
+ u32 value=0;
ssize_t ret = 0;
- char port_status;
-
+ u32 port_status;
+ struct gpio_item *gpio = file->private_data;
+
if (count == 0)
- return bytes_read;
-
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
- if (down_interruptible(&gpio_sema))
- return -ERESTARTSYS;
-
- printk("armadeus_gpio_read on minor %d\n", minor);
-
+ return count;
+
+ spin_lock_irq(&gpio->lock);
+
+ printk("- %s %d byte(s) on minor %d -> %s pin %d\n", __FUNCTION__, count, minor, port_name[gpio->port], gpio->number);
+
+ while (!gpio->changed) {
+ spin_unlock_irq(&gpio->lock);
+
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ if (wait_event_interruptible(gpio->change_wq, gpio->changed))
+ return -ERESTARTSYS;
+
+ spin_lock_irq(&gpio->lock);
+ }
+ gpio->changed = 0;
+
+ if( gpio->nb_pins != 1) {
+ value = readFromPort( gpio->port );
+ printk("Full port read: 0x%x\n", value);
+ } else {
+ value = imx_gpio_get_value( minor );
+ printk("Single pin read: %d\n", value);
+ }
+
value = readFromPort( minor );
port_status = (char)(value & 0xFF);
-
- if (copy_to_user(buf, &port_status, sizeof(unsigned int))) {
+
+ count = min( count, (size_t)sizeof(u32) );
+ if ( copy_to_user(buf, &value, count) ) {
ret = -EFAULT;
goto out;
}
- bytes_read += sizeof(unsigned int);
- buf += sizeof(unsigned int);
- *ppos = *ppos+4;
- ret = bytes_read;
+ ret = count;
out:
- up(&gpio_sema);
+ spin_unlock_irq(&gpio->lock);
return ret;
}
-//
-// Handles open() done on /dev/gpioxx
-//
-static int armadeus_gpio_open(struct inode *inode, struct file *file)
+
+static irqreturn_t armadeus_gpio_interrupt(int irq, void *dev_id)
{
- unsigned minor = MINOR(inode->i_rdev);
-
- if( minor >= PORT_MAX_ID ) {
- printk("unsupported minor\n");
- return -EINVAL;
- }
+ struct gpio_item *gpio = dev_id;
+ u32 old_state, new_state;
- printk("Opening /dev/gpio%d file\n", minor);
- return 0;
+ printk("IT for pin %d %d\n", gpio->port, gpio->number);
+
+ old_state = gpio->pin_state;
+ new_state = imx_gpio_get_value( gpio->port|gpio->number );
+ gpio->pin_state = new_state;
+
+ if (new_state != old_state) {
+ gpio->changed = 1;
+ wake_up_interruptible(&gpio->change_wq);
+
+ if (gpio->async_queue)
+ kill_fasync(&gpio->async_queue, SIGIO, POLL_IN);
+ }
+
+ return IRQ_HANDLED;
}
//
-// Handles close() done on /dev/gpioxx
+// Handles open() done on /dev/gpioxx
//
-static int armadeus_gpio_release(struct inode *inode, struct file *file)
+static int armadeus_gpio_dev_open(struct inode *inode, struct file *file)
{
unsigned minor = MINOR(inode->i_rdev);
-
- printk("Closing access to /dev/gpio%d\n", minor);
- return 0;
-}
+ unsigned int major = MAJOR(inode->i_rdev);
+ unsigned int irq;
+ int ret = 0;
+ struct gpio_item *gpio;/* = container_of(inode->i_cdev, struct gpio_item,
+ char_dev);*/
+ gpio = kzalloc(sizeof(struct gpio_item), GFP_KERNEL);
+ if (!gpio)
+ goto err_request;
-//------------------------------------------------
-// PROC file functions
-//
-static int procfile_gpio_read( char *buffer, __attribute__ ((unused)) char **start, off_t offset, int buffer_length, int *eof, void* data)
-{
- int len; /* The number of bytes actually used */
- unsigned int port_status=0x53;
- unsigned int port_ID = 0;
-
- if( data != NULL )
- {
- port_ID = *((unsigned int*)data);
- //printk("procfile_gpio_read %d \n", port_ID);
- }
-
- // We give all of our information in one go, so if the user asks us if we have more information the answer should always be no.
- // This is important because the standard read function from the library would continue to issue the read system call until
- // the kernel replies that it has no more information, or until its buffer is filled.
-
- if( (offset > 0) || (buffer_length < number_of_pins[port_ID]+2) )
- {
- return 0;
- }
-
- len = buffer_length;
- if( len > MAX_NUMBER_OF_PINS + 1 )
- {
- len = MAX_NUMBER_OF_PINS + 1;
- }
-
- if (down_interruptible(&gpio_sema))
- return -ERESTARTSYS;
-
- // Get the status of the gpio ports
- port_status = readFromPort( port_ID );
-
- // Put status to given chr buffer
- len = toString(port_status, buffer, number_of_pins[/*PORT_B*/port_ID]);
-
- //*start = buffer;
- *eof = 1;
- up(&gpio_sema);
-
- // Return the length
- return len;
-}
+ file->private_data = gpio;
+ spin_lock_init(&gpio->lock);
+ init_waitqueue_head(&gpio->change_wq);
+ switch(minor)
+ {
+ /* Write all port pins in one time */
+ case FULL_PORTA_MINOR:
+ case FULL_PORTB_MINOR:
+ case FULL_PORTC_MINOR:
+ case FULL_PORTD_MINOR:
+ gpio->nb_pins = 32;
+ gpio->changed = 1;
+ gpio->port = FULL_MINOR_TO_PORT(minor);
+ printk("Reserving full %s\n", port_name[gpio->port]);
+ goto success;
+ break;
+ }
-static int procfile_gpio_write( __attribute__ ((unused)) struct file *file, const char *buf, unsigned long count, void *data)
-{
- int len;
- char new_gpio_state[MAX_NUMBER_OF_PINS+1];
- unsigned int gpio_state;
- unsigned int port_ID = 0;
-
- if( data != NULL )
- {
- port_ID = *((unsigned int*)data);
- }
+ /* Pin by pin access */
+ gpio->nb_pins = 1;
+ gpio->changed = 1;
- // Do some checks on parameters
- if( count <= 0 ){
- printk("Empty string transmitted !\n");
- return 0;
- }
- if( count > (MAX_NUMBER_OF_PINS + 1) ) {
- len = MAX_NUMBER_OF_PINS;
- printk("Gpio port is only 32bits !\n");
- } else {
- len = count;
- }
+ if( imx_gpio_request(minor, "gpio-dev") )
+ goto err_request;
- // Get exclusive access to port
- if( down_interruptible(&gpio_sema) )
- return -ERESTARTSYS;
-
- // Get datas to write from user space
- if( copy_from_user(new_gpio_state, buf, len) ) {
- up(&gpio_sema);
- return -EFAULT;
- }
-
- // Convert it from String to Int
- gpio_state = fromString(new_gpio_state, number_of_pins[port_ID] /*__number_of_pins*/);
- printk("/proc asking me to write %d bits (0x%x) on GPIO%d\n", len, gpio_state, port_ID);
+ gpio->port = minor >> GPIO_PORT_SHIFT;
+ gpio->number = minor & GPIO_PIN_MASK;
+ gpio->pin_state = 0;
- // Put value in GPIO registers
- writeOnPort( port_ID, gpio_state );
-
- up(&gpio_sema);
-
- return len;
+ if( getPortDir(gpio->port) & (1 << gpio->number) ) {
+ imx_gpio_direction_output( minor, 0 );
+ } else {
+ imx_gpio_direction_input( minor );
+ gpio->pin_state = imx_gpio_get_value( minor );
+ }
+
+ /* Request interrupt if pin was configured for */
+ if (shadows_irq[gpio->port] & (1 << gpio->number) ) {
+ irq = IRQ_GPIOA(minor); /* irq number are continuous */
+ ret = request_irq( irq, armadeus_gpio_interrupt, 0, "gpio", gpio );
+ if( ret )
+ goto err_irq;
+// set_irq_type( irq, IRQF_TRIGGER_FALLING ); TDBJUJU
+ }
+
+success:
+ printk("Opening /dev/gpio%d/%d file port:%d pin:%d\n", major, minor, gpio->port, gpio->number);
+ gpio->initialized = 1;
+ return 0;
+
+err_irq:
+ printk("%s error while requesting irq %d\n", __FUNCTION__, irq);
+ free_irq(irq, gpio);
+err_request:
+ kfree(gpio);
+ /* what about spinlock & wait_queue ?? */
+ return ret;
}
-static int procfile_settings_read( char *buffer, char **start, off_t offset, int buffer_length, int *eof, __attribute__ ((unused)) void *data )
+//
+// Handles close() done on /dev/gpioxx
+//
+static int armadeus_gpio_dev_release(struct inode *inode, struct file *file)
{
- int len; /* The number of bytes actually used */
- unsigned int port_status = 0x66;
- unsigned int port_ID = 0;
-
- if( data != NULL )
- {
- port_ID = *((unsigned int*)data);
- }
-
- if( offset > 0 || buffer_length < (number_of_pins[PORT_B]+2) )
- return 0;
-
- if (down_interruptible(&gpio_sema))
- return -ERESTARTSYS;
-
- // Get the status of the gpio direction registers TBDNICO
- port_status = getPortDir(port_ID);
- //printk("procfile_settings_read (0x%x)\n", count, gpio_state);
- // Put status to given chr buffer
- len = toString( port_status,buffer, number_of_pins[port_ID] );
-
- //*start = buffer;
- *eof = 1;
- up(&gpio_sema);
-
- // Return the length
- return len;
-}
+ unsigned minor = MINOR(inode->i_rdev);
+ struct gpio_item *gpio = file->private_data;
+ unsigned int irq;
-static int procfile_settings_write( __attribute__ ((unused)) struct file *file, const char *buf, unsigned long count, __attribute__ ((unused)) void* data)
-{
- int len;
- int p1,p2;
- char ch;
- char new_gpio_state[MAX_NUMBER_OF_PINS+1];
- unsigned int gpio_state;
- unsigned int port_ID = 0;
-
- if( data != NULL )
- {
- port_ID = *((unsigned int*)data);
- }
-
- if (count==0) return 0;
-
- if (down_interruptible(&gpio_sema))
- return -ERESTARTSYS;
-
- if( count > (MAX_NUMBER_OF_PINS + 1) ) {
- len = MAX_NUMBER_OF_PINS;
- printk("Gpio port setting register is only 32bits !\n");
- } else {
- len = count;
- }
-
- // Get datas to write from user space
- if(copy_from_user(new_gpio_state, buf, len)) {
- up(&gpio_sema);
- return -EFAULT;
- }
-
- /* make sure our string only contains 1 and 0 */
- p1=0;
- p2=0;
- while (p2<=len)
- {
- ch=new_gpio_state[p2];
-
- if (ch == '0' || ch == '1' || ch == '\0') {
- new_gpio_state[p1] = ch;
- p1++;
- }
-
- if (ch==0) break;
- p2++;
- }
- new_gpio_state[p1] = 0;
-
- if( strlen(new_gpio_state) > 0 )
- {
- // Convert it from String to Int
- gpio_state = fromString( new_gpio_state, number_of_pins[port_ID] );
- printk("/proc asking me to write %d bits (0x%x) on GPIO settings\n", len, gpio_state);
- //
- setPortDir( port_ID, gpio_state );
- }
-
- up(&gpio_sema);
- return len;
+ if( gpio->initialized ) {
+ if (shadows_irq[gpio->port] & (1 << gpio->number) ) {
+ irq = IRQ_GPIOA(minor);
+ free_irq( irq, gpio );
+ }
+ imx_gpio_free( minor );
+ }
+ kfree(gpio);
+ printk("Closing access to /dev/gpio%d\n", minor);
+
+ return 0;
}
-
//------------------------------------------------
-// Handling of IOCTL calls
+// Handling of IOCTL calls
//
-int armadeus_gpio_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg )
+int armadeus_gpio_dev_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg )
{
int err = 0; int ret = 0;
int value=0;
@@ -609,7 +568,7 @@
return -ERESTARTSYS;
// Extract and test minor
minor = MINOR(inode->i_rdev);
- if( minor > GPIO_MAX_MINOR ) {
+ if( minor < FULL_PORTD_MINOR ) {
printk("Minor outside range: %d !\n", minor);
return -EFAULT;
}
@@ -618,7 +577,6 @@
{
case GPIORDDIRECTION:
value = getPortDir( minor );
- // value = (getPortDir( PORT_B ) & PORTB27_21MASK) >> PORTB27_21SHIFT;
ret = __put_user(value, (unsigned int *)arg);
break;
@@ -652,79 +610,260 @@
return ret;
}
+
+//------------------------------------------------
+// PROC file functions
//
-// Create /proc entries for direct access (with echo/cat) to GPIOs config
-//
+
+static int armadeus_gpio_proc_read( char *buffer, char **start, off_t offset, int buffer_length, int *eof, __attribute__ ((unused)) void *data )
+{
+ int len = 0; /* The number of bytes actually used */
+ unsigned int port_status = 0x66;
+ unsigned int port_ID = 0;
+ struct gpio_settings *settings = (struct gpio_settings *) data;
+
+ if( settings != NULL ) {
+ port_ID = settings->port;
+ }
+
+ /* We give all of our information in one go, so if the user asks us if we
+ have more information the answer should always be no. This is important
+ because the standard read function from the library would continue to
+ issue the read system call until the kernel replies that it has no more
+ information, or until its buffer is filled
+ */
+ if( offset > 0 || buffer_length < (number_of_pins[port_ID]+2) )
+ return 0;
+
+ if (down_interruptible(&gpio_sema))
+ return -ERESTARTSYS;
+
+ switch( settings->type )
+ {
+ case VALUE:
+ port_status = readFromPort( port_ID );
+ break;
+
+ case DIRECTION:
+ // Get the status of the gpio direction registers TBDNICO
+ printk("direction\n");
+ port_status = getPortDir(port_ID);
+ break;
+
+ case PULL_UP:
+ port_status = PUEN(port_ID);
+ printk("pull-up\n");
+ break;
+
+ case INTERRUPT:
+ port_status = shadows_irq[port_ID];
+ printk("interrupt\n");
+ break;
+
+ default:
+ printk("%s: unknown setting\n", __FUNCTION__);
+ break;
+ }
+ /* Put result to given chr buffer */
+ len = toString(port_status, buffer, number_of_pins[port_ID]);
+ printk("0x%08x\n", port_status);
+
+ *eof = 1;
+ up(&gpio_sema);
+
+ // Return the length
+ return len;
+}
+
+static char new_gpio_state[MAX_NUMBER_OF_PINS*2];
+
+static int armadeus_gpio_proc_write( __attribute__ ((unused)) struct file *file, const char *buf, unsigned long count, __attribute__ ((unused)) void* data)
+{
+ int len;
+ unsigned int gpio_state;
+ unsigned int port_ID = 0;
+ struct gpio_settings *settings = (struct gpio_settings *) data;
+
+ if( settings != NULL ) {
+ port_ID = settings->port;
+ }
+
+ /* Do some checks on parameters */
+ if( count <= 0 ) {
+ printk("Empty string transmitted !\n");
+ return 0;
+ }
+ if (count > (MAX_NUMBER_OF_PINS + 1))
+ printk("GPIO port registers are only 32bits !\n");
+ if( count > (sizeof(new_gpio_state)) ) {
+ len = sizeof(new_gpio_state);
+ } else {
+ len = count;
+ }
+
+ /* Get exclusive access to port */
+ if( down_interruptible(&gpio_sema) )
+ return -ERESTARTSYS;
+
+ /* Get datas to write from user space */
+ if (copy_from_user(new_gpio_state, buf, len)) {
+ up(&gpio_sema);
+ return -EFAULT;
+ }
+
+ if( strlen(new_gpio_state) > 0 )
+ {
+ // Convert it from String to Int
+ gpio_state = fromString( new_gpio_state, number_of_pins[port_ID] );
+
+ switch( settings->type )
+ {
+ case VALUE:
+ printk("value\n");
+ writeOnPort( port_ID, gpio_state );
+ break;
+
+ case DIRECTION:
+ printk("direction\n");
+ setPortDir( port_ID, gpio_state );
+ break;
+
+ case PULL_UP:
+ printk("pull-up\n");
+ break;
+
+ case INTERRUPT:
+ shadows_irq[port_ID] = gpio_state;
+ printk("interrupt\n");
+ break;
+
+ default:
+ printk("%s: unknown setting\n", __FUNCTION__);
+ break;
+ }
+
+ printk("/proc wrote 0x%x on %s %s register\n", gpio_state, port_name[port_ID], port_setting_name[settings->type]);
+ }
+
+ up(&gpio_sema);
+ return count; /* Makes as if we take all the data send even if we can't handle more than register size */
+}
+
+
+/* /proc registering helpers */
+struct proc_config_entry {
+ struct proc_dir_entry *entry;
+ char* name;
+ int port;
+ int type;
+};
+
+static int initialize_entry( struct proc_config_entry *config )
+{
+ int i;
+
+ for( i=0; i<4; i++ )
+ {
+ config[i].entry = create_proc_entry( config[i].name, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
+ if( config[i].entry == NULL ) {
+ printk(KERN_ERR DRIVER_NAME ": Couldn't register %s. Terminating.\n", config[i].name);
+ return -ENOMEM;
+ }
+
+ config[i].entry->read_proc = armadeus_gpio_proc_read;
+ config[i].entry->write_proc = armadeus_gpio_proc_write;
+ config[i].entry->data = kmalloc(sizeof(struct gpio_settings), GFP_KERNEL);
+ ((struct gpio_settings*) config[i].entry->data)->port = i;
+ ((struct gpio_settings*) config[i].entry->data)->type = config[i].type;
+ }
+
+ return 0;
+}
+
+/*
+ * Create /proc entries for direct access (with echo/cat) to GPIOs config
+ */
static int create_proc_entries( void )
{
- static struct proc_dir_entry *Proc_PortA, *Proc_PortB, *Proc_PortC, *Proc_PortD;
- static struct proc_dir_entry *Proc_PortAdir, *Proc_PortBdir, *Proc_PortCdir, *Proc_PortDdir;
-
- //
+ struct proc_config_entry proc_config[NB_PORTS];
+ int ret;
+
printk("Creating /proc entries: ");
- // Create main directory
+
+ /* Create main directory */
proc_mkdir(GPIO_PROC_DIRNAME, NULL);
-
- // Create proc file to handle GPIO values
- Proc_PortA = create_proc_entry( GPIO_PROC_PORTA_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
- Proc_PortB = create_proc_entry( GPIO_PROC_PORTB_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
- Proc_PortC = create_proc_entry( GPIO_PROC_PORTC_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
- Proc_PortD = create_proc_entry( GPIO_PROC_PORTD_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
- if( (Proc_PortA == NULL) || (Proc_PortB == NULL) )
- {
- printk(KERN_ERR DRIVER_NAME ": Could not register a " GPIO_PROC_PORTA_FILENAME ". Terminating\n");
- armadeus_gpio_cleanup();
- return -ENOMEM;
- }
- else
- {
- Proc_PortA->read_proc = procfile_gpio_read; Proc_PortA->write_proc = procfile_gpio_write; Proc_PortA->data = (void*)&gPortAIndex;
- Proc_PortB->read_proc = procfile_gpio_read; Proc_PortB->write_proc = procfile_gpio_write; Proc_PortB->data = (void*)&gPortBIndex;
- Proc_PortC->read_proc = procfile_gpio_read; Proc_PortC->write_proc = procfile_gpio_write; Proc_PortC->data = (void*)&gPortCIndex;
- Proc_PortD->read_proc = procfile_gpio_read; Proc_PortD->write_proc = procfile_gpio_write; Proc_PortD->data = (void*)&gPortDIndex;
- init_map |= GPIO_PROC_FILE;
- }
-
- // Create proc file to handle GPIO direction settings
- Proc_PortAdir = create_proc_entry( GPIO_PROC_PORTADIR_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
- Proc_PortBdir = create_proc_entry( GPIO_PROC_PORTBDIR_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
- Proc_PortCdir = create_proc_entry( GPIO_PROC_PORTCDIR_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
- Proc_PortDdir = create_proc_entry( GPIO_PROC_PORTDDIR_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
+ /* Create proc file to handle GPIO values */
+ proc_config[PORT_A].name = GPIO_PROC_PORTA_FILENAME;
+ proc_config[PORT_A].type = VALUE;
+ proc_config[PORT_B].name = GPIO_PROC_PORTB_FILENAME;
+ proc_config[PORT_B].type = VALUE;
+ proc_config[PORT_C].name = GPIO_PROC_PORTC_FILENAME;
+ proc_config[PORT_C].type = VALUE;
+ proc_config[PORT_D].name = GPIO_PROC_PORTD_FILENAME;
+ proc_config[PORT_D].type = VALUE;
- if( (Proc_PortAdir == NULL) || (Proc_PortBdir == NULL) )
- {
- printk(KERN_ERR DRIVER_NAME ": Could not register " GPIO_PROC_PORTADIR_FILENAME ". Terminating\n");
- armadeus_gpio_cleanup();
- return -ENOMEM;
- }
- else
- {
- Proc_PortAdir->read_proc = procfile_settings_read; Proc_PortAdir->write_proc = procfile_settings_write;
- Proc_PortAdir->data = (void*)&gPortAIndex;
- Proc_PortBdir->read_proc = procfile_settings_read; Proc_PortBdir->write_proc = procfile_settings_write;
- Proc_PortBdir->data = (void*)&gPortBIndex;
- Proc_PortCdir->read_proc = procfile_settings_read; Proc_PortCdir->write_proc = procfile_settings_write;
- Proc_PortCdir->data = (void*)&gPortCIndex;
- Proc_PortDdir->read_proc = procfile_settings_read; Proc_PortDdir->write_proc = procfile_settings_write;
- Proc_PortDdir->data = (void*)&gPortDIndex;
- init_map |= SETTINGS_PROC_FILE;
- }
+ if( (ret = initialize_entry(proc_config)) )
+ return ret;
+ init_map |= GPIO_PROC_FILE;
+ /* Create proc file to handle GPIO direction settings */
+ proc_config[PORT_A].name = GPIO_PROC_PORTADIR_FILENAME;
+ proc_config[PORT_A].type = DIRECTION;
+ proc_config[PORT_B].name = GPIO_PROC_PORTBDIR_FILENAME;
+ proc_config[PORT_B].type = DIRECTION;
+ proc_config[PORT_C].name = GPIO_PROC_PORTCDIR_FILENAME;
+ proc_config[PORT_C].type = DIRECTION;
+ proc_config[PORT_D].name = GPIO_PROC_PORTDDIR_FILENAME;
+ proc_config[PORT_D].type = DIRECTION;
+
+ if( (ret = initialize_entry(proc_config)) )
+ return ret;
+ init_map |= SETTINGS_PROC_FILE;
+
+ /* Create proc file to handle GPIO interrupt settings */
+ proc_config[PORT_A].name = GPIO_PROC_PORTA_IRQ_FILENAME;
+ proc_config[PORT_A].type = INTERRUPT;
+ proc_config[PORT_B].name = GPIO_PROC_PORTB_IRQ_FILENAME;
+ proc_config[PORT_B].type = INTERRUPT;
+ proc_config[PORT_C].name = GPIO_PROC_PORTC_IRQ_FILENAME;
+ proc_config[PORT_C].type = INTERRUPT;
+ proc_config[PORT_D].name = GPIO_PROC_PORTD_IRQ_FILENAME;
+ proc_config[PORT_D].type = INTERRUPT;
+
+ if( (ret = initialize_entry(proc_config)) )
+ return ret;
+ init_map |= SETTINGS_IRQ_PROC_FILE;
+
+ /* Create proc file to handle GPIO pullup settings */
+ proc_config[PORT_A].name = GPIO_PROC_PORTA_PULLUP_FILENAME;
+ proc_config[PORT_A].type = PULL_UP;
+ proc_config[PORT_B].name = GPIO_PROC_PORTB_PULLUP_FILENAME;
+ proc_config[PORT_B].type = PULL_UP;
+ proc_config[PORT_C].name = GPIO_PROC_PORTC_PULLUP_FILENAME;
+ proc_config[PORT_C].type = PULL_UP;
+ proc_config[PORT_D].name = GPIO_PROC_PORTD_PULLUP_FILENAME;
+ proc_config[PORT_D].type = PULL_UP;
+
+ if( (ret = initialize_entry(proc_config)) )
+ return ret;
+ init_map |= SETTINGS_PULLUP_PROC_FILE;
+
printk("OK!\n");
return(0);
}
//
-// Userspace functionnalities supported:
+// /dev functionnalities supported:
//
static struct file_operations gpio_fops = {
.owner = THIS_MODULE,
- .write = armadeus_gpio_write,
- .read = armadeus_gpio_read,
- .open = armadeus_gpio_open,
- .release = armadeus_gpio_release,
- .ioctl = armadeus_gpio_ioctl,
+ .llseek = no_llseek,
+ .write = armadeus_gpio_dev_write,
+ .read = armadeus_gpio_dev_read,
+ .open = armadeus_gpio_dev_open,
+ .release = armadeus_gpio_dev_release,
+ .ioctl = armadeus_gpio_dev_ioctl,
};
//
@@ -740,29 +879,31 @@
printk(" PortC Parameters (%i): ", portC_init_nb); for( i=0; i< NB_CONFIG_REGS; i++ ) { printk(" 0x%x", portC_init[i]); } printk("\n");
printk(" PortD Parameters (%i): ", portD_init_nb); for( i=0; i< NB_CONFIG_REGS; i++ ) { printk(" 0x%x", portD_init[i]); } printk("\n");
init_map = 0;
-
+
// Configure HW ports/GPIOs with default values or given parameters
initializePorts();
-
- // Register the driver by getting a major number
+
+ /* Register the driver as character device by getting a major number */
result = register_chrdev(gpio_major, DRIVER_NAME, &gpio_fops);
if (result < 0)
{
printk(KERN_WARNING DRIVER_NAME ": can't get major %d\n", gpio_major);
return result;
}
- if( gpio_major == 0 ) gpio_major = result; // dynamic Major allocation
+ if( gpio_major == 0 ) gpio_major = result; /* dynamic Major allocation */
- // Creating /proc entries
- result = create_proc_entries();
- if( result < 0 ) return( result );
-
+ /* Creates /proc entries */
+ if( (result = create_proc_entries()) ) {
+ armadeus_gpio_cleanup();
+ return( result );
+ }
+
// Initialise GPIO port access semaphore
sema_init(&gpio_sema, 1);
// Set GPIOs to initial state
// iMX and parameters will do it
-
+
printk( DRIVER_NAME " " DRIVER_VERSION " successfully loaded !\n");
return(0);
@@ -773,8 +914,10 @@
//
static void __exit armadeus_gpio_cleanup(void)
{
- printk("Cleanup: ");
-
+ printk("Cleanup:\n");
+
+ /* TBDJUJU free config[i].entry->data first ?? */
+
// Remove /proc entries
if( init_map & GPIO_PROC_FILE )
{
@@ -792,15 +935,34 @@
remove_proc_entry( GPIO_PROC_PORTCDIR_FILENAME, NULL);
remove_proc_entry( GPIO_PROC_PORTDDIR_FILENAME, NULL);
}
- // De-register from /dev interface
+ if( init_map & SETTINGS_IRQ_PROC_FILE )
+ {
+ printk( DRIVER_NAME " removing " GPIO_PROC_PORTA_IRQ_FILENAME " & Co\n" );
+ remove_proc_entry( GPIO_PROC_PORTA_IRQ_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTB_IRQ_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTC_IRQ_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTD_IRQ_FILENAME, NULL);
+ }
+ if( init_map & SETTINGS_PULLUP_PROC_FILE )
+ {
+ printk( DRIVER_NAME " removing " GPIO_PROC_PORTA_PULLUP_FILENAME " & Co\n" );
+ remove_proc_entry( GPIO_PROC_PORTA_PULLUP_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTB_PULLUP_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTC_PULLUP_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTD_PULLUP_FILENAME, NULL);
+ }
+
+ remove_proc_entry(GPIO_PROC_DIRNAME, NULL);
+
+ /* De-register from /dev interface */
unregister_chrdev(gpio_major, DRIVER_NAME);
- printk("Ok !\n ");
+ printk("Ok !\n");
}
//------------------------------------------------
//
-// API
+// API TBDJUJU To be removed......
//
void gpioWriteOnPort( unsigned int aPort, unsigned int aValue )
@@ -832,6 +994,7 @@
EXPORT_SYMBOL( gpioSetPortDir );
EXPORT_SYMBOL( gpioGetPortDir );
+
module_init(armadeus_gpio_init);
module_exit(armadeus_gpio_cleanup);
MODULE_AUTHOR("Julien Boibessot / Nicolas Colombain");
Modified: trunk/target/linux/modules/gpio/core.h
===================================================================
--- trunk/target/linux/modules/gpio/core.h 2008-07-29 22:04:58 UTC (rev 865)
+++ trunk/target/linux/modules/gpio/core.h 2008-08-01 16:03:02 UTC (rev 866)
@@ -36,7 +36,9 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/pci.h>
+#include <linux/interrupt.h> /* request_irq */
+#include <asm/gpio.h> /* imx_gpio_... */
+#include <linux/cdev.h> /* struct cdev */
// Proc filenames:
#define GPIO_PROC_DIRNAME "driver/gpio"
@@ -51,10 +53,20 @@
#define GPIO_PROC_PORTCDIR_FILENAME GPIO_PROC_PORTC_FILENAME "dir"
#define GPIO_PROC_PORTDDIR_FILENAME GPIO_PROC_PORTD_FILENAME "dir"
+#define GPIO_PROC_PORTA_IRQ_FILENAME GPIO_PROC_PORTA_FILENAME "irq"
+#define GPIO_PROC_PORTB_IRQ_FILENAME GPIO_PROC_PORTB_FILENAME "irq"
+#define GPIO_PROC_PORTC_IRQ_FILENAME GPIO_PROC_PORTC_FILENAME "irq"
+#define GPIO_PROC_PORTD_IRQ_FILENAME GPIO_PROC_PORTD_FILENAME "irq"
+
+#define GPIO_PROC_PORTA_PULLUP_FILENAME GPIO_PROC_PORTA_FILENAME "pullup"
+#define GPIO_PROC_PORTB_PULLUP_FILENAME GPIO_PROC_PORTB_FILENAME "pullup"
+#define GPIO_PROC_PORTC_PULLUP_FILENAME GPIO_PROC_PORTC_FILENAME "pullup"
+#define GPIO_PROC_PORTD_PULLUP_FILENAME GPIO_PROC_PORTD_FILENAME "pullup"
+
+
// By default, we use dynamic allocation of major numbers -> MAJOR = 0
#define GPIO_MAJOR 0
#define GPIO_MAX_MAJOR 254
-#define GPIO_MAX_MINOR 4
// IOCTL
#define GPIORDDIRECTION _IOR(PP_IOCTL, 0xF0, int) //Read/write bitmask that determines input/output pins (1 means output, 0 input)
@@ -64,7 +76,7 @@
#define MAX_NUMBER_OF_PINS 32
#define DRIVER_NAME "Armadeus GPIOs driver"
-#define DRIVER_VERSION "v1.0"
+#define DRIVER_VERSION "v2.0alpha"
// Pretend we're PPDEV for IOCTL
#include <linux/ppdev.h>
Modified: trunk/target/linux/modules/gpio/loadgpio.sh
===================================================================
--- trunk/target/linux/modules/gpio/loadgpio.sh 2008-07-29 22:04:58 UTC (rev 865)
+++ trunk/target/linux/modules/gpio/loadgpio.sh 2008-08-01 16:03:02 UTC (rev 866)
@@ -1,9 +1,11 @@
-#!/bin/bash
+#!/bin/ash
#
-# This script will load Armadeus gpio modules
+# This script will load Armadeus GPIO modules
#
+GPIO_DEV_DIR=/dev/gpio
+
if [ -d "$1" ]; then
GPIO_MODULES_DIR="$1"
else
@@ -13,23 +15,53 @@
fi
# Load GPIO main module
-insmod $GPIO_MODULES_DIR/gpio.ko portB_init=0,0,0x00FFFF00,0,0,0,0,0,0xF00FFFFF,0,0,0,0,0,0,0x0FF00000 portD_init=0,0xFFFF0000,0xFFFFFFFF,0,0,0,0,0,0xFFFFFFFF,0,0,0,0,0,0,0xFFFFFC00
-# Load PPDEV emultaion module
+#insmod $GPIO_MODULES_DIR/gpio.ko portB_init=0,0,0x00FFFF00,0,0,0,0,0,0xF00FFFFF,0,0,0,0,0,0,0x0FF00000 portD_init=0,0xFFFF0000,0xFFFFFFFF,0,0,0,0,0,0xFFFFFFFF,0,0,0,0,0,0,0xFFFFFC00
+insmod $GPIO_MODULES_DIR/gpio.ko
+# Load PPDEV emulation module
insmod $GPIO_MODULES_DIR/ppdev.ko port_mode=4
-GPIO_MAJOR=`cat /proc/devices | grep gpio | cut -d " " -f 1`
+GPIO_MAJOR=`cat /proc/devices | grep GPIO | cut -d " " -f 1`
PPDEV_MAJOR=`cat /proc/devices | grep ppdev | cut -d " " -f 1`
+if [ "$GPIO_MAJOR" == "" ]; then
+ echo "GPIO module not loaded, exiting"
+ exit 1
+fi
+
mkdir -p /dev/parports
-mkdir -p /dev/gpio
+mkdir -p $GPIO_DEV_DIR
# For PPDEV
-mknod /dev/parports/0 c $PPDEV_MAJOR 0
+if [ "$PPDEV_MAJOR" != "" ]; then
+ mknod /dev/parports/0 c $PPDEV_MAJOR 0
+fi
-# For general usage
-mknod /dev/gpio/portA c $GPIO_MAJOR 0
-mknod /dev/gpio/portB c $GPIO_MAJOR 1
-mknod /dev/gpio/portC c $GPIO_MAJOR 2
-mknod /dev/gpio/portD c $GPIO_MAJOR 3
+# /dev for "full" port access:
+mknod $GPIO_DEV_DIR/portA c $GPIO_MAJOR 255
+mknod $GPIO_DEV_DIR/portB c $GPIO_MAJOR 254
+mknod $GPIO_DEV_DIR/portC c $GPIO_MAJOR 253
+mknod $GPIO_DEV_DIR/portD c $GPIO_MAJOR 252
+# /dev for individual pin access:
+# PortA[0-31]
+for pin in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31; do
+ minor=$pin
+ mknod $GPIO_DEV_DIR/PA$pin c $GPIO_MAJOR $minor
+done
+# PortB[8-31]
+for pin in 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31; do
+ minor=$((32+$pin))
+ mknod $GPIO_DEV_DIR/PB$pin c $GPIO_MAJOR $minor
+done
+# PortC[3-17]
+for pin in 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17; do
+ minor=$((64+$pin))
+ mknod $GPIO_DEV_DIR/PC$pin c $GPIO_MAJOR $minor
+done
+# PortD[6-31]
+for pin in 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31; do
+ minor=$((96+$pin))
+ mknod $GPIO_DEV_DIR/PD$pin c $GPIO_MAJOR $minor
+done
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-07-29 22:04:50
|
Revision: 865
http://armadeus.svn.sourceforge.net/armadeus/?rev=865&view=rev
Author: artemys
Date: 2008-07-29 22:04:58 +0000 (Tue, 29 Jul 2008)
Log Message:
-----------
[LINUX] FPGA's irq_manager driver should not be compiled if not selected
Modified Paths:
--------------
trunk/target/linux/modules/fpga/irq_manager/Kconfig
trunk/target/linux/modules/fpga/irq_manager/Makefile
Modified: trunk/target/linux/modules/fpga/irq_manager/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/irq_manager/Kconfig 2008-07-29 15:53:55 UTC (rev 864)
+++ trunk/target/linux/modules/fpga/irq_manager/Kconfig 2008-07-29 22:04:58 UTC (rev 865)
@@ -1,7 +1,7 @@
#
#
-config ARMADEUS_FPGA_IRG_MANAGER
+config ARMADEUS_FPGA_IRQ_MANAGER
tristate "OpenCore IRQ manager driver"
default n
depends on ARMADEUS_FPGA_DRIVERS
Modified: trunk/target/linux/modules/fpga/irq_manager/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/irq_manager/Makefile 2008-07-29 15:53:55 UTC (rev 864)
+++ trunk/target/linux/modules/fpga/irq_manager/Makefile 2008-07-29 22:04:58 UTC (rev 865)
@@ -6,10 +6,10 @@
# Part executed when called from kernel build system:
-obj-m += irq_ocore.o
+obj-$(CONFIG_ARMADEUS_FPGA_IRQ_MANAGER) += irq_ocore.o
irq_ocore-objs := main.o
-obj-m += test_irq.o
+obj-$(CONFIG_ARMADEUS_FPGA_IRQ_MANAGER) += test_irq.o
test_irq-objs := test.o
else
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-07-29 15:53:46
|
Revision: 864
http://armadeus.svn.sourceforge.net/armadeus/?rev=864&view=rev
Author: artemys
Date: 2008-07-29 15:53:55 +0000 (Tue, 29 Jul 2008)
Log Message:
-----------
[LINUX] Add some (temporary) kernel patches to test serial and irq IPs, forgot something ;-)
Modified Paths:
--------------
trunk/target/linux/modules/fpga/irq_manager/200-hack-kernel-to-export-some-irq-handling-functions.diff
trunk/target/linux/modules/fpga/serial/200-hack-8250-layer-to-force-no-interrupt-mode.diff
Modified: trunk/target/linux/modules/fpga/irq_manager/200-hack-kernel-to-export-some-irq-handling-functions.diff
===================================================================
--- trunk/target/linux/modules/fpga/irq_manager/200-hack-kernel-to-export-some-irq-handling-functions.diff 2008-07-29 15:51:26 UTC (rev 863)
+++ trunk/target/linux/modules/fpga/irq_manager/200-hack-kernel-to-export-some-irq-handling-functions.diff 2008-07-29 15:53:55 UTC (rev 864)
@@ -1,7 +1,6 @@
COPY IT IN buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/
-diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/arch/arm/kernel/irq.c buildroot/build_arm/linux-2.6.23.1.irq_manager/arch/arm/kernel/irq.c
---- buildroot/build_arm/linux-2.6.23.1/arch/arm/kernel/irq.c 2007-10-12 18:43:44.000000000 +0200
-+++ buildroot/build_arm/linux-2.6.23.1.irq_manager/arch/arm/kernel/irq.c 2008-07-24 16:43:52.000000000 +0200
+--- linux-2.6.23.1/arch/arm/kernel/irq.c 2007-10-12 18:43:44.000000000 +0200
++++ linux-2.6.23.1.irq_manager/arch/arm/kernel/irq.c 2008-07-24 16:43:52.000000000 +0200
@@ -152,6 +152,7 @@
desc->status &= ~IRQ_NOAUTOEN;
spin_unlock_irqrestore(&desc->lock, flags);
@@ -10,9 +9,8 @@
void __init init_IRQ(void)
{
-diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/include/asm-arm/arch-imx/irqs.h buildroot/build_arm/linux-2.6.23.1.irq_manager/include/asm-arm/arch-imx/irqs.h
---- buildroot/build_arm/linux-2.6.23.1/include/asm-arm/arch-imx/irqs.h 2008-07-29 17:26:13.000000000 +0200
-+++ buildroot/build_arm/linux-2.6.23.1.irq_manager/include/asm-arm/arch-imx/irqs.h 2008-07-24 17:26:17.000000000 +0200
+--- linux-2.6.23.1/include/asm-arm/arch-imx/irqs.h 2008-07-29 17:26:13.000000000 +0200
++++ linux-2.6.23.1.irq_manager/include/asm-arm/arch-imx/irqs.h 2008-07-24 17:26:17.000000000 +0200
@@ -112,6 +112,10 @@
/* decode irq number to use with IMR(x), ISR(x) and friends */
#define IRQ_TO_REG(irq) ((irq - IMX_IRQS) >> 5)
@@ -25,9 +23,8 @@
+#define NR_IRQS (IRQ_FPGA(16) + 1)
#define IRQ_GPIO(x)
#endif
-diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/kernel/irq/chip.c buildroot/build_arm/linux-2.6.23.1.irq_manager/kernel/irq/chip.c
---- buildroot/build_arm/linux-2.6.23.1/kernel/irq/chip.c 2007-10-12 18:43:44.000000000 +0200
-+++ buildroot/build_arm/linux-2.6.23.1.irq_manager/kernel/irq/chip.c 2008-07-24 16:47:35.000000000 +0200
+--- linux-2.6.23.1/kernel/irq/chip.c 2007-10-12 18:43:44.000000000 +0200
++++ linux-2.6.23.1.irq_manager/kernel/irq/chip.c 2008-07-24 16:47:35.000000000 +0200
@@ -502,6 +502,7 @@
out_unlock:
spin_unlock(&desc->lock);
@@ -52,9 +49,8 @@
void
set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
-diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/kernel/irq/handle.c buildroot/build_arm/linux-2.6.23.1.irq_manager/kernel/irq/handle.c
---- buildroot/build_arm/linux-2.6.23.1/kernel/irq/handle.c 2007-10-12 18:43:44.000000000 +0200
-+++ buildroot/build_arm/linux-2.6.23.1.irq_manager/kernel/irq/handle.c 2008-07-24 17:02:07.000000000 +0200
+--- linux-2.6.23.1/kernel/irq/handle.c 2007-10-12 18:43:44.000000000 +0200
++++ linux-2.6.23.1.irq_manager/kernel/irq/handle.c 2008-07-24 17:02:07.000000000 +0200
@@ -59,6 +59,7 @@
#endif
}
Modified: trunk/target/linux/modules/fpga/serial/200-hack-8250-layer-to-force-no-interrupt-mode.diff
===================================================================
--- trunk/target/linux/modules/fpga/serial/200-hack-8250-layer-to-force-no-interrupt-mode.diff 2008-07-29 15:51:26 UTC (rev 863)
+++ trunk/target/linux/modules/fpga/serial/200-hack-8250-layer-to-force-no-interrupt-mode.diff 2008-07-29 15:53:55 UTC (rev 864)
@@ -1,7 +1,6 @@
COPY IT IN buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/
-diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/drivers/serial/8250.c buildroot/build_arm/linux-2.6.23.1.irq_manager/drivers/serial/8250.c
---- buildroot/build_arm/linux-2.6.23.1/drivers/serial/8250.c 2007-10-12 18:43:44.000000000 +0200
-+++ buildroot/build_arm/linux-2.6.23.1.irq_manager/drivers/serial/8250.c 2008-07-23 15:20:08.000000000 +0200
+--- linux-2.6.23.1/drivers/serial/8250.c 2007-10-12 18:43:44.000000000 +0200
++++ linux-2.6.23.1.irq_manager/drivers/serial/8250.c 2008-07-23 15:20:08.000000000 +0200
@@ -58,7 +58,7 @@
/*
* Debugging.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-07-29 15:51:19
|
Revision: 863
http://armadeus.svn.sourceforge.net/armadeus/?rev=863&view=rev
Author: artemys
Date: 2008-07-29 15:51:26 +0000 (Tue, 29 Jul 2008)
Log Message:
-----------
[LINUX] Add some (temporary) kernel patches to test serial and irq IPs
Added Paths:
-----------
trunk/target/linux/modules/fpga/irq_manager/200-hack-kernel-to-export-some-irq-handling-functions.diff
trunk/target/linux/modules/fpga/serial/200-hack-8250-layer-to-force-no-interrupt-mode.diff
Added: trunk/target/linux/modules/fpga/irq_manager/200-hack-kernel-to-export-some-irq-handling-functions.diff
===================================================================
--- trunk/target/linux/modules/fpga/irq_manager/200-hack-kernel-to-export-some-irq-handling-functions.diff (rev 0)
+++ trunk/target/linux/modules/fpga/irq_manager/200-hack-kernel-to-export-some-irq-handling-functions.diff 2008-07-29 15:51:26 UTC (rev 863)
@@ -0,0 +1,65 @@
+COPY IT IN buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/
+diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/arch/arm/kernel/irq.c buildroot/build_arm/linux-2.6.23.1.irq_manager/arch/arm/kernel/irq.c
+--- buildroot/build_arm/linux-2.6.23.1/arch/arm/kernel/irq.c 2007-10-12 18:43:44.000000000 +0200
++++ buildroot/build_arm/linux-2.6.23.1.irq_manager/arch/arm/kernel/irq.c 2008-07-24 16:43:52.000000000 +0200
+@@ -152,6 +152,7 @@
+ desc->status &= ~IRQ_NOAUTOEN;
+ spin_unlock_irqrestore(&desc->lock, flags);
+ }
++EXPORT_SYMBOL(set_irq_flags);
+
+ void __init init_IRQ(void)
+ {
+diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/include/asm-arm/arch-imx/irqs.h buildroot/build_arm/linux-2.6.23.1.irq_manager/include/asm-arm/arch-imx/irqs.h
+--- buildroot/build_arm/linux-2.6.23.1/include/asm-arm/arch-imx/irqs.h 2008-07-29 17:26:13.000000000 +0200
++++ buildroot/build_arm/linux-2.6.23.1.irq_manager/include/asm-arm/arch-imx/irqs.h 2008-07-24 17:26:17.000000000 +0200
+@@ -112,6 +112,10 @@
+ /* decode irq number to use with IMR(x), ISR(x) and friends */
+ #define IRQ_TO_REG(irq) ((irq - IMX_IRQS) >> 5)
+
+-#define NR_IRQS (IRQ_GPIOD(32) + 1)
++#define IRQ_FPGA_START (IRQ_GPIOD(32) + 1)
++#define IRQ_FPGA(x) (IRQ_FPGA_START + x)
++
++//#define NR_IRQS (IRQ_GPIOD(32) + 1)
++#define NR_IRQS (IRQ_FPGA(16) + 1)
+ #define IRQ_GPIO(x)
+ #endif
+diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/kernel/irq/chip.c buildroot/build_arm/linux-2.6.23.1.irq_manager/kernel/irq/chip.c
+--- buildroot/build_arm/linux-2.6.23.1/kernel/irq/chip.c 2007-10-12 18:43:44.000000000 +0200
++++ buildroot/build_arm/linux-2.6.23.1.irq_manager/kernel/irq/chip.c 2008-07-24 16:47:35.000000000 +0200
+@@ -502,6 +502,7 @@
+ out_unlock:
+ spin_unlock(&desc->lock);
+ }
++EXPORT_SYMBOL(handle_edge_irq);
+
+ #ifdef CONFIG_SMP
+ /**
+@@ -581,6 +582,7 @@
+ }
+ spin_unlock_irqrestore(&desc->lock, flags);
+ }
++EXPORT_SYMBOL(__set_irq_handler);
+
+ void
+ set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
+@@ -589,6 +591,7 @@
+ set_irq_chip(irq, chip);
+ __set_irq_handler(irq, handle, 0, NULL);
+ }
++EXPORT_SYMBOL(set_irq_chip_and_handler);
+
+ void
+ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
+diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/kernel/irq/handle.c buildroot/build_arm/linux-2.6.23.1.irq_manager/kernel/irq/handle.c
+--- buildroot/build_arm/linux-2.6.23.1/kernel/irq/handle.c 2007-10-12 18:43:44.000000000 +0200
++++ buildroot/build_arm/linux-2.6.23.1.irq_manager/kernel/irq/handle.c 2008-07-24 17:02:07.000000000 +0200
+@@ -59,6 +59,7 @@
+ #endif
+ }
+ };
++EXPORT_SYMBOL(irq_desc);
+
+ /*
+ * What should we do if we get a hw irq event on an illegal vector?
Added: trunk/target/linux/modules/fpga/serial/200-hack-8250-layer-to-force-no-interrupt-mode.diff
===================================================================
--- trunk/target/linux/modules/fpga/serial/200-hack-8250-layer-to-force-no-interrupt-mode.diff (rev 0)
+++ trunk/target/linux/modules/fpga/serial/200-hack-8250-layer-to-force-no-interrupt-mode.diff 2008-07-29 15:51:26 UTC (rev 863)
@@ -0,0 +1,181 @@
+COPY IT IN buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/
+diff -urN -X buildroot/build_arm/linux-2.6.23.1/Documentation/dontdiff buildroot/build_arm/linux-2.6.23.1/drivers/serial/8250.c buildroot/build_arm/linux-2.6.23.1.irq_manager/drivers/serial/8250.c
+--- buildroot/build_arm/linux-2.6.23.1/drivers/serial/8250.c 2007-10-12 18:43:44.000000000 +0200
++++ buildroot/build_arm/linux-2.6.23.1.irq_manager/drivers/serial/8250.c 2008-07-23 15:20:08.000000000 +0200
+@@ -58,7 +58,7 @@
+ /*
+ * Debugging.
+ */
+-#if 0
++#if 1
+ #define DEBUG_AUTOCONF(fmt...) printk(fmt)
+ #else
+ #define DEBUG_AUTOCONF(fmt...) do { } while (0)
+@@ -77,7 +77,7 @@
+ * machine types want others as well - they're free
+ * to redefine this in their header file.
+ */
+-#define is_real_interrupt(irq) ((irq) != 0)
++#define is_real_interrupt(irq) ((irq) != 65)
+
+ #ifdef CONFIG_SERIAL_8250_DETECT_IRQ
+ #define CONFIG_SERIAL_DETECT_IRQ 1
+@@ -992,6 +992,8 @@
+ unsigned char save_lcr, save_mcr;
+ unsigned long flags;
+
++ printk("autoconfig\n");
++
+ if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
+ return;
+
+@@ -1170,6 +1172,8 @@
+ unsigned long irqs;
+ int irq;
+
++ printk("autoconfig_irq\n");
++
+ if (up->port.flags & UPF_FOURPORT) {
+ ICP = (up->port.iobase & 0xfe0) | 0x1f;
+ save_ICP = inb_p(ICP);
+@@ -1746,6 +1750,8 @@
+ unsigned char lsr, iir;
+ int retval;
+
++ printk("serial8250_startup\n");
++
+ up->capabilities = uart_config[up->port.type].flags;
+ up->mcr = 0;
+
+@@ -1840,7 +1846,7 @@
+ * kick the UART on a regular basis.
+ */
+ if (iir & UART_IIR_NO_INT) {
+- pr_debug("ttyS%d - using backup timer\n", port->line);
++ printk("ttyS%d - using backup timer\n", port->line);
+ up->timer.function = serial8250_backup_timeout;
+ up->timer.data = (unsigned long)up;
+ mod_timer(&up->timer, jiffies +
+@@ -2195,6 +2201,8 @@
+ unsigned int size = 8 << up->port.regshift;
+ int ret = 0;
+
++ printk("serial8250_request_std_resource: ");
++
+ switch (up->port.iotype) {
+ case UPIO_AU:
+ size = 0x100000;
+@@ -2208,6 +2216,7 @@
+
+ if (!request_mem_region(up->port.mapbase, size, "serial")) {
+ ret = -EBUSY;
++ printk("BUSY");
+ break;
+ }
+
+@@ -2216,6 +2225,7 @@
+ if (!up->port.membase) {
+ release_mem_region(up->port.mapbase, size);
+ ret = -ENOMEM;
++ printk("NOMEM");
+ }
+ }
+ break;
+@@ -2226,6 +2236,7 @@
+ ret = -EBUSY;
+ break;
+ }
++ printk("\n");
+ return ret;
+ }
+
+@@ -2233,6 +2244,7 @@
+ {
+ unsigned int size = 8 << up->port.regshift;
+
++ printk("serial8250_release_std_resource\n");
+ switch (up->port.iotype) {
+ case UPIO_AU:
+ size = 0x100000;
+@@ -2296,6 +2308,8 @@
+ {
+ struct uart_8250_port *up = (struct uart_8250_port *)port;
+
++ printk("serial8250_release_port\n");
++
+ serial8250_release_std_resource(up);
+ if (up->port.type == PORT_RSA)
+ serial8250_release_rsa_resource(up);
+@@ -2306,6 +2320,8 @@
+ struct uart_8250_port *up = (struct uart_8250_port *)port;
+ int ret = 0;
+
++ printk("serial8250_request_port\n");
++
+ ret = serial8250_request_std_resource(up);
+ if (ret == 0 && up->port.type == PORT_RSA) {
+ ret = serial8250_request_rsa_resource(up);
+@@ -2322,6 +2338,7 @@
+ int probeflags = PROBE_ANY;
+ int ret;
+
++ printk("serial8250_config_port 0x%x\n", flags);
+ /*
+ * Find the region that we can probe for. This in turn
+ * tells us whether we can probe for the type of port.
+@@ -2341,8 +2358,9 @@
+
+ if (up->port.type != PORT_RSA && probeflags & PROBE_RSA)
+ serial8250_release_rsa_resource(up);
+- if (up->port.type == PORT_UNKNOWN)
++ if (up->port.type == PORT_UNKNOWN) {
+ serial8250_release_std_resource(up);
++ }
+ }
+
+ static int
+@@ -2661,7 +2679,9 @@
+
+ memset(&port, 0, sizeof(struct uart_port));
+
++ printk("serial8250_probe\n");
+ for (i = 0; p && p->flags != 0; p++, i++) {
++ printk("---\n");
+ port.iobase = p->iobase;
+ port.membase = p->membase;
+ port.irq = p->irq;
+@@ -2764,6 +2784,7 @@
+ if (uart_match_port(&serial8250_ports[i].port, port))
+ return &serial8250_ports[i];
+
++ printk("serial8250_find_match_or_unused: 1\n");
+ /*
+ * We didn't find a matching entry, so look for the first
+ * free entry. We look for one which hasn't been previously
+@@ -2774,6 +2795,8 @@
+ serial8250_ports[i].port.iobase == 0)
+ return &serial8250_ports[i];
+
++ printk("serial8250_find_match_or_unused: 2\n");
++
+ /*
+ * That also failed. Last resort is to find any entry which
+ * doesn't have a real port associated with it.
+@@ -2782,6 +2805,8 @@
+ if (serial8250_ports[i].port.type == PORT_UNKNOWN)
+ return &serial8250_ports[i];
+
++ printk("serial8250_find_match_or_unused: none\n");
++
+ return NULL;
+ }
+
+@@ -2803,6 +2828,8 @@
+ struct uart_8250_port *uart;
+ int ret = -ENOSPC;
+
++ printk("serial8250_register_port\n");
++
+ if (port->uartclk == 0)
+ return -EINVAL;
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-07-29 14:25:01
|
Revision: 862
http://armadeus.svn.sourceforge.net/armadeus/?rev=862&view=rev
Author: artemys
Date: 2008-07-29 14:25:09 +0000 (Tue, 29 Jul 2008)
Log Message:
-----------
[LINUX] Add driver for OpenCore IRQ manager (generated by POD)
Modified Paths:
--------------
trunk/target/linux/modules/Makefile
trunk/target/linux/modules/fpga/Kconfig
Added Paths:
-----------
trunk/target/linux/modules/fpga/Makefile
trunk/target/linux/modules/fpga/irq_manager/
trunk/target/linux/modules/fpga/irq_manager/Kconfig
trunk/target/linux/modules/fpga/irq_manager/Makefile
trunk/target/linux/modules/fpga/irq_manager/README
trunk/target/linux/modules/fpga/irq_manager/main.c
trunk/target/linux/modules/fpga/irq_manager/test.c
Modified: trunk/target/linux/modules/Makefile
===================================================================
--- trunk/target/linux/modules/Makefile 2008-07-28 15:23:57 UTC (rev 861)
+++ trunk/target/linux/modules/Makefile 2008-07-29 14:25:09 UTC (rev 862)
@@ -9,8 +9,7 @@
# Part executed when called from kernel build system:
obj-$(CONFIG_ARMADEUS_DRIVERS) += gpio/ pwm/ backlight/ isp1761/ \
- fpga/ps2keyboard/ imxlkeypad/ fpga/fpga_devtools/ fpga/Wb_led/ fpga/Wb_button/ \
- fpga/i2ctest/ fpga/fpgaaccess/ fpga/serial/
+ imxlkeypad/ fpga/
else
Modified: trunk/target/linux/modules/fpga/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/Kconfig 2008-07-28 15:23:57 UTC (rev 861)
+++ trunk/target/linux/modules/fpga/Kconfig 2008-07-29 14:25:09 UTC (rev 862)
@@ -25,5 +25,7 @@
source "drivers/armadeus/fpga/serial/Kconfig"
+source "drivers/armadeus/fpga/irq_manager/Kconfig"
+
endmenu
Added: trunk/target/linux/modules/fpga/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/Makefile 2008-07-29 14:25:09 UTC (rev 862)
@@ -0,0 +1,42 @@
+#
+# Main Makefile for the Armadeus FPGA related drivers
+#
+# Add your subdirectories to obj- target
+#
+
+ifneq ($(KERNELRELEASE),)
+
+# Part executed when called from kernel build system:
+
+obj-$(CONFIG_ARMADEUS_FPGA_DRIVERS) += ps2keyboard/ fpga_devtools/ Wb_led/ Wb_button/ \
+ i2ctest/ fpgaaccess/ serial/ irq_manager/
+
+else
+
+# Part executed when called from standard make in this directory:
+
+BASE_DIR:=../../../../buildroot/
+REL:=$(shell grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+ sed -e 's/BR2_PACKAGE_LINUX_VERSION=//' | sed -e 's/"//g')
+#`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR).config | \
+# sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+ARMADEUS_KERNEL_DIR:=$(BASE_DIR)build_arm/linux-$(REL)
+ifeq ($(LINUX_DIR),)
+LINUX_DIR:=$(ARMADEUS_KERNEL_DIR)
+endif
+PWD:= $(shell pwd)
+
+default:
+ echo "Your Linux source dir is: $(LINUX_DIR)"
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) zImage modules
+
+clean:
+ echo "Your Linux source dir is: $(LINUX_DIR)"
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) clean
+
+install:
+ echo "Installing Armadeus drivers..."
+ $(MAKE) -C $(LINUX_DIR) SUBDIRS=$(PWD) INSTALL_MOD_PATH=$(TARGET_DIR) modules_install
+
+endif
+
Property changes on: trunk/target/linux/modules/fpga/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fpga/irq_manager/Kconfig
===================================================================
--- trunk/target/linux/modules/fpga/irq_manager/Kconfig (rev 0)
+++ trunk/target/linux/modules/fpga/irq_manager/Kconfig 2008-07-29 14:25:09 UTC (rev 862)
@@ -0,0 +1,10 @@
+#
+#
+
+config ARMADEUS_FPGA_IRG_MANAGER
+ tristate "OpenCore IRQ manager driver"
+ default n
+ depends on ARMADEUS_FPGA_DRIVERS
+ ---help---
+ You need it if you have a POD generated "IP"
+
Added: trunk/target/linux/modules/fpga/irq_manager/Makefile
===================================================================
--- trunk/target/linux/modules/fpga/irq_manager/Makefile (rev 0)
+++ trunk/target/linux/modules/fpga/irq_manager/Makefile 2008-07-29 14:25:09 UTC (rev 862)
@@ -0,0 +1,38 @@
+#
+# Makefile for the Armadeus FPGA OpenCore IRQ manager IP
+#
+
+ifneq ($(KERNELRELEASE),)
+
+# Part executed when called from kernel build system:
+
+obj-m += irq_ocore.o
+irq_ocore-objs := main.o
+
+obj-m += test_irq.o
+test_irq-objs := test.o
+
+else
+
+# Part executed when called from standard make in this directory:
+# (preferably use Makefile in parent directory)
+
+BASE_DIR=../../../../../buildroot
+REL=`grep "BR2_PACKAGE_LINUX_VERSION=" $(BASE_DIR)/.config | \
+ sed "s/BR2_PACKAGE_LINUX_VERSION=\\"//" | sed "s/\\"//"`
+BUILD_ARM=`ls $(BASE_DIR) | grep "^build_arm"`
+ARMADEUS_KERNEL_DIR=$(BASE_DIR)/$(BUILD_ARM)/linux-$(REL)
+KDIR := $(ARMADEUS_KERNEL_DIR)
+PWD := $(shell pwd)
+
+default:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+
+clean:
+ rm -f *.*o
+ rm -f Module.symvers
+ rm -rf .*.cmd
+ rm -f *.mod.c
+
+endif
+
Property changes on: trunk/target/linux/modules/fpga/irq_manager/Makefile
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/modules/fpga/irq_manager/README
===================================================================
--- trunk/target/linux/modules/fpga/irq_manager/README (rev 0)
+++ trunk/target/linux/modules/fpga/irq_manager/README 2008-07-29 14:25:09 UTC (rev 862)
@@ -0,0 +1,8 @@
+To compile this driver from here:
+---------------------------------
+ make ARCH=arm CROSS_COMPILE=$PWD/../../../../../buildroot/build_arm/staging_dir/bin/arm-linux-
+
+To install this driver:
+-----------------------
+Copy resulting *.ko files on your target rootfs
+
Added: trunk/target/linux/modules/fpga/irq_manager/main.c
===================================================================
--- trunk/target/linux/modules/fpga/irq_manager/main.c (rev 0)
+++ trunk/target/linux/modules/fpga/irq_manager/main.c 2008-07-29 14:25:09 UTC (rev 862)
@@ -0,0 +1,161 @@
+/*
+ * Driver for the IRQ manager loaded in FPGA of the Armadeus boards
+ *
+ * (C) Copyright 2008 Armadeus Systems
+ * Author: Julien Boibessot <jul...@ar...>
+ *
+ * Inspired of linux/arch/arm/mach-imx/irq.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/irqs.h>
+#include <asm/irq.h>
+#include <asm/io.h> // readb() & Co
+
+#include <asm/mach/irq.h>
+
+#if 0
+#define DEBUG_FPGA_IRQ(fmt...) printk(fmt)
+#else
+#define DEBUG_FPGA_IRQ(fmt...) do { } while (0)
+#endif
+
+
+/* --- Things to be configured by POD --- */
+#define FPGA_IMR (APF9328_FPGA_VIRT + 0x00) /* Interrupt Mask Register */
+#define FPGA_ISR (APF9328_FPGA_VIRT + 0x02) /* Interrupt Status Register */
+#define NB_IT (16)
+/* -------------------------------------- */
+
+
+static int
+imx_fpga_irq_type(unsigned int _irq, unsigned int type)
+{
+ return 0;
+}
+
+static void
+imx_fpga_ack_irq(unsigned int irq)
+{
+ int shadow;
+
+ shadow = 1 << ((irq - IRQ_FPGA_START) % NB_IT);
+ DEBUG_FPGA_IRQ("%s: irq %d ack:0x%x\n", __FUNCTION__, irq, shadow);
+ writew( shadow, FPGA_ISR );
+
+ /* if last IT ack GPIO global IRQ */
+ if( readw(FPGA_ISR) == 0 )
+ ISR(IRQ_TO_REG(APF9328_FPGA_IRQ)) = 1 << (APF9328_FPGA_IRQ - IRQ_GPIOA(0));
+}
+
+static void
+imx_fpga_mask_irq(unsigned int irq)
+{
+ int shadow;
+
+ shadow = readw(FPGA_IMR);
+ shadow &= ~( 1 << ((irq - IRQ_FPGA_START) % NB_IT));
+ DEBUG_FPGA_IRQ("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow);
+ writew( shadow, FPGA_IMR );
+}
+
+static void
+imx_fpga_unmask_irq(unsigned int irq)
+{
+ int shadow;
+
+ shadow = readw(FPGA_IMR);
+ shadow |= 1 << ((irq - IRQ_FPGA_START) % NB_IT);
+ DEBUG_FPGA_IRQ("%s: irq %d mask:0x%x\n", __FUNCTION__, irq, shadow);
+ writew( shadow, FPGA_IMR );
+}
+
+static void
+imx_fpga_handler(unsigned int mask, unsigned int irq,
+ struct irq_desc *desc)
+{
+ DEBUG_FPGA_IRQ("%s: mask:0x%x\n", __FUNCTION__, mask);
+ desc = irq_desc + irq;
+ while (mask) {
+ if (mask & 1) {
+ DEBUG_FPGA_IRQ("handling irq %d\n", irq);
+ desc_handle_irq(irq, desc);
+ }
+ irq++;
+ desc++;
+ mask >>= 1;
+ }
+}
+
+static void
+imx_fpga_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
+{
+ unsigned int mask, irq;
+
+ mask = readw(FPGA_ISR);
+ irq = IRQ_FPGA_START;
+ imx_fpga_handler(mask, irq, desc);
+}
+
+static struct irq_chip imx_fpga_chip = {
+ .name = "FPGA",
+ .ack = imx_fpga_ack_irq,
+ .mask = imx_fpga_mask_irq,
+ .unmask = imx_fpga_unmask_irq,
+ .set_type = imx_fpga_irq_type,
+};
+
+
+static int __init ocore_irq_mng_init(void)
+{
+ unsigned int irq;
+
+ DEBUG_FPGA_IRQ("Initializing FPGA IRQs\n");
+
+ /* Mask all interrupts initially */
+ writew(0, FPGA_IMR);
+
+ for (irq = IRQ_FPGA(0); irq < IRQ_FPGA(NB_IT-1); irq++) {
+ set_irq_chip_and_handler( irq, &imx_fpga_chip, handle_edge_irq );
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ set_irq_chained_handler(APF9328_FPGA_IRQ, imx_fpga_demux_handler);
+
+ DEBUG_FPGA_IRQ("IRQs initialized\n");
+
+ return 0;
+}
+
+static void __exit ocore_irq_mng_exit(void)
+{
+ /* Should we allow to remove this module ?? */
+ DEBUG_FPGA_IRQ("%s\n", __FUNCTION__);
+}
+
+module_init(ocore_irq_mng_init);
+module_exit(ocore_irq_mng_exit);
+
+MODULE_AUTHOR("Julien Boibessot, <jul...@ar...>");
+MODULE_DESCRIPTION("Armadeus OpenCore IRQ manager");
+MODULE_LICENSE("GPL");
Added: trunk/target/linux/modules/fpga/irq_manager/test.c
===================================================================
--- trunk/target/linux/modules/fpga/irq_manager/test.c (rev 0)
+++ trunk/target/linux/modules/fpga/irq_manager/test.c 2008-07-29 14:25:09 UTC (rev 862)
@@ -0,0 +1,81 @@
+/*
+ * Driver to test OpenCore IRQ manager driver
+ *
+ * Copyright (C) 2008 Armadeus Systems
+ * Author: Julien Boibessot <jul...@ar...>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/config.h>
+#endif
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+
+
+/* Module's parameters: */
+static int interrupt=IRQ_FPGA(3);
+module_param(interrupt, int, 0000);
+MODULE_PARM_DESC(interrupt, "IT to request");
+
+#define DRIVER_NAME "IRQ test module"
+
+
+static irqreturn_t fpga_interrupt(int irq,void *dev_id,struct pt_regs *reg)
+{
+ printk(KERN_ERR "FPGA IT n°%d\n", irq);
+
+ return IRQ_HANDLED;
+}
+
+unsigned int data;
+
+static int __init irq_mng_test_init(void)
+{
+ int result;
+
+ /* IRQ registering */
+ if( (result=request_irq( interrupt, (irq_handler_t)fpga_interrupt, /*IRQF_SHARED*/0, "ocore_irq_test", &data)) < 0 )
+ {
+ printk(KERN_ERR "Can't request IRQ n°%d\n", interrupt);
+ goto error;
+ }
+
+ printk(KERN_INFO DRIVER_NAME " inserted (IRQ %d reserved), be sure to have correspondig IP loaded in the FPGA !\n", interrupt);
+ return 0;
+
+error:
+ return result;
+}
+
+static void __exit irq_mng_test_exit(void)
+{
+ printk(DRIVER_NAME " unloaded\n");
+ free_irq(interrupt, 0); /* still a bug here ! */
+}
+
+
+module_init(irq_mng_test_init);
+module_exit(irq_mng_test_exit);
+
+MODULE_AUTHOR("Julien Boibessot, <jul...@ar...>");
+MODULE_DESCRIPTION("OpenCore IRQ manager IP's test driver");
+MODULE_LICENSE("GPL");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-07-28 15:23:54
|
Revision: 861
http://armadeus.svn.sourceforge.net/armadeus/?rev=861&view=rev
Author: artemys
Date: 2008-07-28 15:23:57 +0000 (Mon, 28 Jul 2008)
Log Message:
-----------
[LINUX] Add automatic generation of 013-imxfb patch + removing of PWM register update when doing imxfb_set_par()
Modified Paths:
--------------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-imxfb-improvements.diff
trunk/target/linux/Makefile
Added Paths:
-----------
trunk/target/linux/drivers/
trunk/target/linux/drivers/video/
trunk/target/linux/drivers/video/imxfb.c
Modified: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-imxfb-improvements.diff
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-imxfb-improvements.diff 2008-07-28 14:23:47 UTC (rev 860)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-imxfb-improvements.diff 2008-07-28 15:23:57 UTC (rev 861)
@@ -1,7 +1,8 @@
---- linux-2.6.23/drivers/video/imxfb.c 2006-09-20 05:42:06.000000000 +0200
-+++ linux-2.6.23-imx/drivers/video/imxfb.c 2006-10-01 14:22:39.000000000 +0200
-18:43:44.000000000 +0200
-+++ imxfb.c 2008-01-15 01:50:45.000000000 +0100
+PATCH AUTOMATICALLY GENERATED
+DON'T EDIT IT OR YOUR MODIFICATIONS WILL BE LOST
+(Take a look at armadeus/target/linux/ directory to know how to generate it)
+--- linux-2.6.23.1.original/drivers/video/imxfb.c 2007-10-12 18:43:44.000000000 +0200
++++ linux-2.6.23.1.mod/drivers/video/imxfb.c 2008-07-28 16:58:52.000000000 +0200
@@ -42,22 +42,48 @@
*/
#define DEBUG_VAR 1
@@ -63,7 +64,7 @@
static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info);
static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
-@@ -152,7 +178,6 @@ static int
+@@ -152,7 +178,6 @@
imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct imxfb_info *fbi = info->par;
@@ -71,7 +72,7 @@
if (var->xres < MIN_XRES)
var->xres = MIN_XRES;
-@@ -165,27 +190,39 @@ imxfb_check_var(struct fb_var_screeninfo
+@@ -165,27 +190,39 @@
var->xres_virtual = max(var->xres_virtual, var->xres);
var->yres_virtual = max(var->yres_virtual, var->yres);
@@ -125,7 +126,7 @@
pr_debug("RGBT length = %d:%d:%d:%d\n",
var->red.length, var->green.length, var->blue.length,
var->transp.length);
-@@ -248,10 +285,11 @@ static void imxfb_enable_controller(stru
+@@ -248,10 +285,11 @@
LCDC_RMCR = RMCR_LCDC_EN;
@@ -139,7 +140,7 @@
}
static void imxfb_disable_controller(struct imxfb_info *fbi)
-@@ -312,6 +350,7 @@ static int imxfb_activate_var(struct fb_
+@@ -312,6 +350,7 @@
pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
var->yres, var->vsync_len,
var->upper_margin, var->lower_margin);
@@ -147,11 +148,14 @@
#if DEBUG_VAR
if (var->xres < 16 || var->xres > 1024)
-@@ -349,7 +388,17 @@ static int imxfb_activate_var(struct fb_
+@@ -349,10 +388,17 @@
VCR_V_WAIT_2(var->lower_margin);
LCDC_SIZE = SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres);
- LCDC_PCR = fbi->pcr;
+- LCDC_PWMR = fbi->pwmr;
+- LCDC_LSCR1 = fbi->lscr1;
+- LCDC_DMACR = fbi->dmacr;
+ // On TFT LCD i.MXL can support 16, 12, 8, 4bpp with the same hardware interface (12 to 16 bits)
+ // So if userspace app wants a 8bpp screen switch to 8bpp (can save ressources, with SDL for ex)
+ if( (var->bits_per_pixel == 8) && (fbi->pcr & PCR_TFT) )
@@ -163,10 +167,10 @@
+ LCDC_PCR = fbi->pcr;
+
+ LCDC_VPW = VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4);
- LCDC_PWMR = fbi->pwmr;
- LCDC_LSCR1 = fbi->lscr1;
- LCDC_DMACR = fbi->dmacr;
-@@ -391,7 +440,26 @@ static void imxfb_setup_gpio(struct imxf
+
+ return 0;
+ }
+@@ -391,7 +437,26 @@
case 1:
imx_gpio_mode(PD15_PF_LD0);
}
@@ -193,7 +197,7 @@
/* initialize GPIOs */
imx_gpio_mode(PD6_PF_LSCLK);
imx_gpio_mode(PD11_PF_CONTRAST);
-@@ -406,6 +474,7 @@ static void imxfb_setup_gpio(struct imxf
+@@ -406,6 +471,7 @@
imx_gpio_mode(PD9_PF_PS);
imx_gpio_mode(PD10_PF_SPL_SPR);
}
@@ -201,7 +205,7 @@
}
#ifdef CONFIG_PM
-@@ -469,9 +538,6 @@ static int __init imxfb_init_fbinfo(stru
+@@ -469,9 +535,6 @@
info->fbops = &imxfb_ops;
info->flags = FBINFO_FLAG_DEFAULT;
@@ -211,10 +215,24 @@
fbi->max_xres = inf->xres;
info->var.xres = inf->xres;
info->var.xres_virtual = inf->xres;
-Index: drivers/video/imxfb.h
-===================================================================
---- a/drivers/video/imxfb.h
-+++ b//dev/null
+@@ -596,6 +659,12 @@
+ imxfb_setup_gpio(fbi);
+
+ imxfb_set_par(info);
++ /* JB: The following parameters are only needed once at startup and so
++ removed from from imxfb_set_par()/imxfb_activate_var() */
++ LCDC_PWMR = fbi->pwmr;
++ LCDC_LSCR1 = fbi->lscr1;
++ LCDC_DMACR = fbi->dmacr;
++
+ ret = register_framebuffer(info);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to register framebuffer\n");
+PATCH AUTOMATICALLY GENERATED
+DON'T EDIT IT OR YOUR MODIFICATIONS WILL BE LOST
+(Take a look at armadeus/target/linux/ directory to know how to generate it)
+--- linux-2.6.23.1.original/drivers/video/imxfb.h 2007-10-12 18:43:44.000000000 +0200
++++ linux-2.6.23.1.mod/drivers/video/imxfb.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,73 +0,0 @@
-/*
- * linux/drivers/video/imxfb.h
Modified: trunk/target/linux/Makefile
===================================================================
--- trunk/target/linux/Makefile 2008-07-28 14:23:47 UTC (rev 860)
+++ trunk/target/linux/Makefile 2008-07-28 15:23:57 UTC (rev 861)
@@ -64,7 +64,21 @@
### Other Patches: ---
+# Special case: drivers/video/imxfb.h doesn't exist
+FILES_O1=drivers/video/imxfb.c drivers/video/imxfb.h
+DEP_O1=drivers/video/imxfb.c
+TARGET_O1:=$(TMP_DIR)/013-imxfb-improvements.diff
+$(TARGET_O1): $(DEP_O1)
+ @$(START_CMD)
+ rm -f $@
+ for file in $(FILES_O1); do $(PATCH_CMD) --append $(LINUX_DIR_TO_DIFF)/$$file ../linux/$$file $@; echo " adding $$file"; done
+ @$(CLEAN_PATCH_CMD)
+ @echo
+PATCHES+=$(TARGET_O1)
+FILES+=$(FILES_O1)
+
+
### Patches generation: ---
.PHONY: clean all help show import patch patch_install
@@ -82,7 +96,7 @@
patch_install: patch
@cp -a $(PATCHES) $(PATCH_DIR)/
@echo "Patches installed, you can check the diff in $(PATCH_DIR)/"
- @echo " please don't commit only timestamp changes !"
+ @echo " please don't commit <<timestamp only>> changes !"
show:
@echo "Linux kernel files ($(LINUX_VERSION)) from which I can generate patch:"
@@ -91,7 +105,7 @@
@for patch in $(PATCHES); do echo " $$patch"; done
import:
- @for file in $(FILES); do cp $(LINUX_DIR)/$$file $$file; done
+ @for file in $(FILES); do if [ -f $(LINUX_DIR)/$$file ]; then cp $(LINUX_DIR)/$$file $$file; fi; done
@echo "Import done, check your modifications with svn status -q"
help:
Added: trunk/target/linux/drivers/video/imxfb.c
===================================================================
--- trunk/target/linux/drivers/video/imxfb.c (rev 0)
+++ trunk/target/linux/drivers/video/imxfb.c 2008-07-28 15:23:57 UTC (rev 861)
@@ -0,0 +1,749 @@
+/*
+ * linux/drivers/video/imxfb.c
+ *
+ * Freescale i.MX Frame Buffer device driver
+ *
+ * Copyright (C) 2004 Sascha Hauer, Pengutronix
+ * Based on acornfb.c Copyright (C) Russell King.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Please direct your questions and comments on this driver to the following
+ * email address:
+ *
+ * lin...@li...
+ */
+
+//#define DEBUG 1
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/arch/imxfb.h>
+
+/*
+ * Complain if VAR is out of range.
+ */
+#define DEBUG_VAR 1
+
+struct imxfb_info {
+ struct device *dev;
+
+ u_int max_bpp;
+ u_int max_xres;
+ u_int max_yres;
+
+ /*
+ * These are the addresses we mapped
+ * the framebuffer memory region to.
+ */
+ dma_addr_t map_dma;
+ u_char * map_cpu;
+ u_int map_size;
+
+ u_char * screen_cpu;
+ dma_addr_t screen_dma;
+ u_int palette_size;
+
+ dma_addr_t dbar1;
+ dma_addr_t dbar2;
+
+ u_int pcr;
+ u_int pwmr;
+ u_int lscr1;
+ u_int dmacr;
+ u_int cmap_inverse:1,
+ cmap_static:1,
+ unused:30;
+
+ void (*lcd_power)(int);
+ void (*backlight_power)(int);
+};
+
+#define IMX_NAME "IMX"
+
+/*
+ * Minimum X and Y resolutions
+ */
+#define MIN_XRES 64
+#define MIN_YRES 64
+
+static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info);
+
+static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+#define LCDC_PALETTE(x) __REG2(IMX_LCDC_BASE+0x800, (x)<<2)
+static int
+imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int trans, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+ u_int val, ret = 1;
+
+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
+ if (regno < fbi->palette_size) {
+ val = (CNVT_TOHW(red, 4) << 8) |
+ (CNVT_TOHW(green,4) << 4) |
+ CNVT_TOHW(blue, 4);
+
+ LCDC_PALETTE(regno) = val;
+ ret = 0;
+ }
+ return ret;
+}
+
+static int
+imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int trans, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+ unsigned int val;
+ int ret = 1;
+
+ /*
+ * If inverse mode was selected, invert all the colours
+ * rather than the register number. The register number
+ * is what you poke into the framebuffer to produce the
+ * colour you requested.
+ */
+ if (fbi->cmap_inverse) {
+ red = 0xffff - red;
+ green = 0xffff - green;
+ blue = 0xffff - blue;
+ }
+
+ /*
+ * If greyscale is true, then we convert the RGB value
+ * to greyscale no mater what visual we are using.
+ */
+ if (info->var.grayscale)
+ red = green = blue = (19595 * red + 38470 * green +
+ 7471 * blue) >> 16;
+
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /*
+ * 12 or 16-bit True Colour. We encode the RGB value
+ * according to the RGB bitfield information.
+ */
+ if (regno < 16) {
+ u32 *pal = info->pseudo_palette;
+
+ val = chan_to_field(red, &info->var.red);
+ val |= chan_to_field(green, &info->var.green);
+ val |= chan_to_field(blue, &info->var.blue);
+
+ pal[regno] = val;
+ ret = 0;
+ }
+ break;
+
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ ret = imxfb_setpalettereg(regno, red, green, blue, trans, info);
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * imxfb_check_var():
+ * Round up in the following order: bits_per_pixel, xres,
+ * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+ * bitfields, horizontal timing, vertical timing.
+ */
+static int
+imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+
+ if (var->xres < MIN_XRES)
+ var->xres = MIN_XRES;
+ if (var->yres < MIN_YRES)
+ var->yres = MIN_YRES;
+ if (var->xres > fbi->max_xres)
+ var->xres = fbi->max_xres;
+ if (var->yres > fbi->max_yres)
+ var->yres = fbi->max_yres;
+ var->xres_virtual = max(var->xres_virtual, var->xres);
+ var->yres_virtual = max(var->yres_virtual, var->yres);
+
+ memset(&var->transp, 0, sizeof(var->transp));
+
+ pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
+ switch (var->bits_per_pixel) {
+ case 8:
+ var->red.length = var->bits_per_pixel;
+ var->red.offset = 0;
+ var->green.length = var->bits_per_pixel;
+ var->green.offset = 0;
+ var->blue.length = var->bits_per_pixel;
+ var->blue.offset = 0;
+ break;
+ case 16:
+ if (fbi->pcr & PCR_TFT) {
+ var->red.length = 5;
+ var->red.offset = 11;
+ var->green.length = 6;
+ var->green.offset = 5;
+ var->blue.length = 5;
+ var->blue.offset = 0;
+ } else {
+ var->red.length = 4;
+ var->red.offset = 8;
+ var->green.length = 4;
+ var->green.offset = 4;
+ var->blue.length = 4;
+ var->blue.offset = 0;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ pr_debug("RGBT length = %d:%d:%d:%d\n",
+ var->red.length, var->green.length, var->blue.length,
+ var->transp.length);
+
+ pr_debug("RGBT offset = %d:%d:%d:%d\n",
+ var->red.offset, var->green.offset, var->blue.offset,
+ var->transp.offset);
+
+ return 0;
+}
+
+/*
+ * imxfb_set_par():
+ * Set the user defined part of the display for the specified console
+ */
+static int imxfb_set_par(struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+ struct fb_var_screeninfo *var = &info->var;
+
+ pr_debug("set_par\n");
+
+ if (var->bits_per_pixel == 16)
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ else if (!fbi->cmap_static)
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ else {
+ /*
+ * Some people have weird ideas about wanting static
+ * pseudocolor maps. I suspect their user space
+ * applications are broken.
+ */
+ info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+ }
+
+ info->fix.line_length = var->xres_virtual *
+ var->bits_per_pixel / 8;
+ fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
+
+ imxfb_activate_var(var, info);
+
+ return 0;
+}
+
+static void imxfb_enable_controller(struct imxfb_info *fbi)
+{
+ pr_debug("Enabling LCD controller\n");
+
+ /* initialize LCDC */
+ LCDC_RMCR &= ~RMCR_LCDC_EN; /* just to be safe... */
+
+ LCDC_SSA = fbi->screen_dma;
+ /* physical screen start address */
+ LCDC_VPW = VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4);
+
+ LCDC_POS = 0x00000000; /* panning offset 0 (0 pixel offset) */
+
+ /* disable hardware cursor */
+ LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1);
+
+ LCDC_RMCR = RMCR_LCDC_EN;
+
+ if(fbi->lcd_power)
+ fbi->lcd_power(1);
+ /* enable backlight after LCD */
+ if(fbi->backlight_power)
+ fbi->backlight_power(1);
+}
+
+static void imxfb_disable_controller(struct imxfb_info *fbi)
+{
+ pr_debug("Disabling LCD controller\n");
+
+ if(fbi->backlight_power)
+ fbi->backlight_power(0);
+ if(fbi->lcd_power)
+ fbi->lcd_power(0);
+
+ LCDC_RMCR = 0;
+}
+
+static int imxfb_blank(int blank, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+
+ pr_debug("imxfb_blank: blank=%d\n", blank);
+
+ switch (blank) {
+ case FB_BLANK_POWERDOWN:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_NORMAL:
+ imxfb_disable_controller(fbi);
+ break;
+
+ case FB_BLANK_UNBLANK:
+ imxfb_enable_controller(fbi);
+ break;
+ }
+ return 0;
+}
+
+static struct fb_ops imxfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = imxfb_check_var,
+ .fb_set_par = imxfb_set_par,
+ .fb_setcolreg = imxfb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_blank = imxfb_blank,
+};
+
+/*
+ * imxfb_activate_var():
+ * Configures LCD Controller based on entries in var parameter. Settings are
+ * only written to the controller if changes were made.
+ */
+static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+ pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
+ var->xres, var->hsync_len,
+ var->left_margin, var->right_margin);
+ pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
+ var->yres, var->vsync_len,
+ var->upper_margin, var->lower_margin);
+ pr_debug("var: bpp=%d\n", var->bits_per_pixel);
+
+#if DEBUG_VAR
+ if (var->xres < 16 || var->xres > 1024)
+ printk(KERN_ERR "%s: invalid xres %d\n",
+ info->fix.id, var->xres);
+ if (var->hsync_len < 1 || var->hsync_len > 64)
+ printk(KERN_ERR "%s: invalid hsync_len %d\n",
+ info->fix.id, var->hsync_len);
+ if (var->left_margin > 255)
+ printk(KERN_ERR "%s: invalid left_margin %d\n",
+ info->fix.id, var->left_margin);
+ if (var->right_margin > 255)
+ printk(KERN_ERR "%s: invalid right_margin %d\n",
+ info->fix.id, var->right_margin);
+ if (var->yres < 1 || var->yres > 511)
+ printk(KERN_ERR "%s: invalid yres %d\n",
+ info->fix.id, var->yres);
+ if (var->vsync_len > 100)
+ printk(KERN_ERR "%s: invalid vsync_len %d\n",
+ info->fix.id, var->vsync_len);
+ if (var->upper_margin > 63)
+ printk(KERN_ERR "%s: invalid upper_margin %d\n",
+ info->fix.id, var->upper_margin);
+ if (var->lower_margin > 255)
+ printk(KERN_ERR "%s: invalid lower_margin %d\n",
+ info->fix.id, var->lower_margin);
+#endif
+
+ LCDC_HCR = HCR_H_WIDTH(var->hsync_len) |
+ HCR_H_WAIT_1(var->left_margin) |
+ HCR_H_WAIT_2(var->right_margin);
+
+ LCDC_VCR = VCR_V_WIDTH(var->vsync_len) |
+ VCR_V_WAIT_1(var->upper_margin) |
+ VCR_V_WAIT_2(var->lower_margin);
+
+ LCDC_SIZE = SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres);
+ // On TFT LCD i.MXL can support 16, 12, 8, 4bpp with the same hardware interface (12 to 16 bits)
+ // So if userspace app wants a 8bpp screen switch to 8bpp (can save ressources, with SDL for ex)
+ if( (var->bits_per_pixel == 8) && (fbi->pcr & PCR_TFT) )
+ {
+ pr_debug("Switching imxfb to 8bpp\n");
+ LCDC_PCR = (fbi->pcr & (~PCR_BPIX_MASK)) | PCR_BPIX_8 | PCR_END_BYTE_SWAP;
+ }
+ else
+ LCDC_PCR = fbi->pcr;
+
+ LCDC_VPW = VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4);
+
+ return 0;
+}
+
+static void imxfb_setup_gpio(struct imxfb_info *fbi)
+{
+ int width;
+
+ LCDC_RMCR &= ~(RMCR_LCDC_EN | RMCR_SELF_REF);
+
+ if( fbi->pcr & PCR_TFT )
+ width = 16;
+ else
+ width = 1 << ((fbi->pcr >> 28) & 0x3);
+
+ switch(width) {
+ case 16:
+ imx_gpio_mode(PD30_PF_LD15);
+ imx_gpio_mode(PD29_PF_LD14);
+ imx_gpio_mode(PD28_PF_LD13);
+ imx_gpio_mode(PD27_PF_LD12);
+ imx_gpio_mode(PD26_PF_LD11);
+ imx_gpio_mode(PD25_PF_LD10);
+ imx_gpio_mode(PD24_PF_LD9);
+ imx_gpio_mode(PD23_PF_LD8);
+ case 8:
+ imx_gpio_mode(PD22_PF_LD7);
+ imx_gpio_mode(PD21_PF_LD6);
+ imx_gpio_mode(PD20_PF_LD5);
+ imx_gpio_mode(PD19_PF_LD4);
+ case 4:
+ imx_gpio_mode(PD18_PF_LD3);
+ imx_gpio_mode(PD17_PF_LD2);
+ case 2:
+ imx_gpio_mode(PD16_PF_LD1);
+ case 1:
+ imx_gpio_mode(PD15_PF_LD0);
+ }
+#ifdef CONFIG_MACH_APF9328
+ /* initialize standard GPIOs */
+ imx_gpio_mode(PD6_PF_LSCLK);
+ imx_gpio_mode(PD14_PF_FLM_VSYNC);
+ imx_gpio_mode(PD13_PF_LP_HSYNC);
+// imx_gpio_mode(PD12_PF_ACD_OE);
+
+ /* if != 0 */
+ if( fbi->pwmr ) {
+ imx_gpio_mode(PD11_PF_CONTRAST);
+ }
+
+ /* sharp display specific */
+ if( fbi->pcr & PCR_SHARP ) {
+ imx_gpio_mode(PD10_PF_SPL_SPR);
+ imx_gpio_mode(PD7_PF_REV);
+ imx_gpio_mode(PD8_PF_CLS);
+ imx_gpio_mode(PD9_PF_PS);
+ }
+#else
+ /* initialize GPIOs */
+ imx_gpio_mode(PD6_PF_LSCLK);
+ imx_gpio_mode(PD11_PF_CONTRAST);
+ imx_gpio_mode(PD14_PF_FLM_VSYNC);
+ imx_gpio_mode(PD13_PF_LP_HSYNC);
+ imx_gpio_mode(PD12_PF_ACD_OE);
+
+ /* These are only needed for Sharp HR TFT displays */
+ if (fbi->pcr & PCR_SHARP) {
+ imx_gpio_mode(PD7_PF_REV);
+ imx_gpio_mode(PD8_PF_CLS);
+ imx_gpio_mode(PD9_PF_PS);
+ imx_gpio_mode(PD10_PF_SPL_SPR);
+ }
+#endif //CONFIG_MACH_APF9328
+}
+
+#ifdef CONFIG_PM
+/*
+ * Power management hooks. Note that we won't be called from IRQ context,
+ * unlike the blank functions above, so we may sleep.
+ */
+static int imxfb_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct imxfb_info *fbi = platform_get_drvdata(dev);
+ pr_debug("%s\n",__FUNCTION__);
+
+ imxfb_disable_controller(fbi);
+ return 0;
+}
+
+static int imxfb_resume(struct platform_device *dev)
+{
+ struct imxfb_info *fbi = platform_get_drvdata(dev);
+ pr_debug("%s\n",__FUNCTION__);
+
+ imxfb_enable_controller(fbi);
+ return 0;
+}
+#else
+#define imxfb_suspend NULL
+#define imxfb_resume NULL
+#endif
+
+static int __init imxfb_init_fbinfo(struct device *dev)
+{
+ struct imxfb_mach_info *inf = dev->platform_data;
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct imxfb_info *fbi = info->par;
+
+ pr_debug("%s\n",__FUNCTION__);
+
+ info->pseudo_palette = kmalloc( sizeof(u32) * 16, GFP_KERNEL);
+ if (!info->pseudo_palette)
+ return -ENOMEM;
+
+ memset(fbi, 0, sizeof(struct imxfb_info));
+ fbi->dev = dev;
+
+ strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));
+
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.type_aux = 0;
+ info->fix.xpanstep = 0;
+ info->fix.ypanstep = 0;
+ info->fix.ywrapstep = 0;
+ info->fix.accel = FB_ACCEL_NONE;
+
+ info->var.nonstd = 0;
+ info->var.activate = FB_ACTIVATE_NOW;
+ info->var.height = -1;
+ info->var.width = -1;
+ info->var.accel_flags = 0;
+ info->var.vmode = FB_VMODE_NONINTERLACED;
+
+ info->fbops = &imxfb_ops;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ fbi->max_xres = inf->xres;
+ info->var.xres = inf->xres;
+ info->var.xres_virtual = inf->xres;
+ fbi->max_yres = inf->yres;
+ info->var.yres = inf->yres;
+ info->var.yres_virtual = inf->yres;
+ fbi->max_bpp = inf->bpp;
+ info->var.bits_per_pixel = inf->bpp;
+ info->var.pixclock = inf->pixclock;
+ info->var.hsync_len = inf->hsync_len;
+ info->var.left_margin = inf->left_margin;
+ info->var.right_margin = inf->right_margin;
+ info->var.vsync_len = inf->vsync_len;
+ info->var.upper_margin = inf->upper_margin;
+ info->var.lower_margin = inf->lower_margin;
+ info->var.sync = inf->sync;
+ info->var.grayscale = inf->cmap_greyscale;
+ fbi->cmap_inverse = inf->cmap_inverse;
+ fbi->cmap_static = inf->cmap_static;
+ fbi->pcr = inf->pcr;
+ fbi->lscr1 = inf->lscr1;
+ fbi->dmacr = inf->dmacr;
+ fbi->pwmr = inf->pwmr;
+ fbi->lcd_power = inf->lcd_power;
+ fbi->backlight_power = inf->backlight_power;
+ info->fix.smem_len = fbi->max_xres * fbi->max_yres *
+ fbi->max_bpp / 8;
+
+ return 0;
+}
+
+/*
+ * Allocates the DRAM memory for the frame buffer. This buffer is
+ * remapped into a non-cached, non-buffered, memory region to
+ * allow pixel writes to occur without flushing the cache.
+ * Once this area is remapped, all virtual memory access to the
+ * video memory should occur at the new region.
+ */
+static int __init imxfb_map_video_memory(struct fb_info *info)
+{
+ struct imxfb_info *fbi = info->par;
+
+ fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
+ fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
+ &fbi->map_dma,GFP_KERNEL);
+
+ if (fbi->map_cpu) {
+ info->screen_base = fbi->map_cpu;
+ fbi->screen_cpu = fbi->map_cpu;
+ fbi->screen_dma = fbi->map_dma;
+ info->fix.smem_start = fbi->screen_dma;
+ }
+
+ return fbi->map_cpu ? 0 : -ENOMEM;
+}
+
+static int __init imxfb_probe(struct platform_device *pdev)
+{
+ struct imxfb_info *fbi;
+ struct fb_info *info;
+ struct imxfb_mach_info *inf;
+ struct resource *res;
+ int ret;
+
+ printk("i.MX Framebuffer driver\n");
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if(!res)
+ return -ENODEV;
+
+ inf = pdev->dev.platform_data;
+ if(!inf) {
+ dev_err(&pdev->dev,"No platform_data available\n");
+ return -ENOMEM;
+ }
+
+ info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);
+ if(!info)
+ return -ENOMEM;
+
+ fbi = info->par;
+
+ platform_set_drvdata(pdev, info);
+
+ ret = imxfb_init_fbinfo(&pdev->dev);
+ if( ret < 0 )
+ goto failed_init;
+
+ res = request_mem_region(res->start, res->end - res->start + 1, "IMXFB");
+ if (!res) {
+ ret = -EBUSY;
+ goto failed_regs;
+ }
+
+ if (!inf->fixed_screen_cpu) {
+ ret = imxfb_map_video_memory(info);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
+ ret = -ENOMEM;
+ goto failed_map;
+ }
+ } else {
+ /* Fixed framebuffer mapping enables location of the screen in eSRAM */
+ fbi->map_cpu = inf->fixed_screen_cpu;
+ fbi->map_dma = inf->fixed_screen_dma;
+ info->screen_base = fbi->map_cpu;
+ fbi->screen_cpu = fbi->map_cpu;
+ fbi->screen_dma = fbi->map_dma;
+ info->fix.smem_start = fbi->screen_dma;
+ }
+
+ /*
+ * This makes sure that our colour bitfield
+ * descriptors are correctly initialised.
+ */
+ imxfb_check_var(&info->var, info);
+
+ ret = fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
+ if (ret < 0)
+ goto failed_cmap;
+
+ imxfb_setup_gpio(fbi);
+
+ imxfb_set_par(info);
+ /* JB: The following parameters are only needed once at startup and so
+ removed from from imxfb_set_par()/imxfb_activate_var() */
+ LCDC_PWMR = fbi->pwmr;
+ LCDC_LSCR1 = fbi->lscr1;
+ LCDC_DMACR = fbi->dmacr;
+
+ ret = register_framebuffer(info);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to register framebuffer\n");
+ goto failed_register;
+ }
+
+ imxfb_enable_controller(fbi);
+
+ return 0;
+
+failed_register:
+ fb_dealloc_cmap(&info->cmap);
+failed_cmap:
+ if (!inf->fixed_screen_cpu)
+ dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
+ fbi->map_dma);
+failed_map:
+ kfree(info->pseudo_palette);
+failed_regs:
+ release_mem_region(res->start, res->end - res->start);
+failed_init:
+ platform_set_drvdata(pdev, NULL);
+ framebuffer_release(info);
+ return ret;
+}
+
+static int imxfb_remove(struct platform_device *pdev)
+{
+ struct fb_info *info = platform_get_drvdata(pdev);
+ struct imxfb_info *fbi = info->par;
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ imxfb_disable_controller(fbi);
+
+ unregister_framebuffer(info);
+
+ fb_dealloc_cmap(&info->cmap);
+ kfree(info->pseudo_palette);
+ framebuffer_release(info);
+
+ release_mem_region(res->start, res->end - res->start + 1);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+void imxfb_shutdown(struct platform_device * dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct imxfb_info *fbi = info->par;
+ imxfb_disable_controller(fbi);
+}
+
+static struct platform_driver imxfb_driver = {
+ .probe = imxfb_probe,
+ .suspend = imxfb_suspend,
+ .resume = imxfb_resume,
+ .remove = imxfb_remove,
+ .shutdown = imxfb_shutdown,
+ .driver = {
+ .name = "imx-fb",
+ },
+};
+
+int __init imxfb_init(void)
+{
+ return platform_driver_register(&imxfb_driver);
+}
+
+static void __exit imxfb_cleanup(void)
+{
+ platform_driver_unregister(&imxfb_driver);
+}
+
+module_init(imxfb_init);
+module_exit(imxfb_cleanup);
+
+MODULE_DESCRIPTION("Motorola i.MX framebuffer driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-07-28 14:23:41
|
Revision: 860
http://armadeus.svn.sourceforge.net/armadeus/?rev=860&view=rev
Author: artemys
Date: 2008-07-28 14:23:47 +0000 (Mon, 28 Jul 2008)
Log Message:
-----------
[LINUX] Rename 013 patch (in 2.6.23)
Added Paths:
-----------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-imxfb-improvements.diff
Removed Paths:
-------------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff
Copied: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-imxfb-improvements.diff (from rev 859, trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff)
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-imxfb-improvements.diff (rev 0)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-imxfb-improvements.diff 2008-07-28 14:23:47 UTC (rev 860)
@@ -0,0 +1,291 @@
+--- linux-2.6.23/drivers/video/imxfb.c 2006-09-20 05:42:06.000000000 +0200
++++ linux-2.6.23-imx/drivers/video/imxfb.c 2006-10-01 14:22:39.000000000 +0200
+18:43:44.000000000 +0200
++++ imxfb.c 2008-01-15 01:50:45.000000000 +0100
+@@ -42,22 +42,48 @@
+ */
+ #define DEBUG_VAR 1
+
+-#include "imxfb.h"
++struct imxfb_info {
++ struct device *dev;
+
+-static struct imxfb_rgb def_rgb_16 = {
+- .red = { .offset = 8, .length = 4, },
+- .green = { .offset = 4, .length = 4, },
+- .blue = { .offset = 0, .length = 4, },
+- .transp = { .offset = 0, .length = 0, },
+-};
++ u_int max_bpp;
++ u_int max_xres;
++ u_int max_yres;
++
++ /*
++ * These are the addresses we mapped
++ * the framebuffer memory region to.
++ */
++ dma_addr_t map_dma;
++ u_char * map_cpu;
++ u_int map_size;
++
++ u_char * screen_cpu;
++ dma_addr_t screen_dma;
++ u_int palette_size;
++
++ dma_addr_t dbar1;
++ dma_addr_t dbar2;
++
++ u_int pcr;
++ u_int pwmr;
++ u_int lscr1;
++ u_int dmacr;
++ u_int cmap_inverse:1,
++ cmap_static:1,
++ unused:30;
+
+-static struct imxfb_rgb def_rgb_8 = {
+- .red = { .offset = 0, .length = 8, },
+- .green = { .offset = 0, .length = 8, },
+- .blue = { .offset = 0, .length = 8, },
+- .transp = { .offset = 0, .length = 0, },
++ void (*lcd_power)(int);
++ void (*backlight_power)(int);
+ };
+
++#define IMX_NAME "IMX"
++
++/*
++ * Minimum X and Y resolutions
++ */
++#define MIN_XRES 64
++#define MIN_YRES 64
++
+ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info);
+
+ static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
+@@ -152,7 +178,6 @@ static int
+ imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+ {
+ struct imxfb_info *fbi = info->par;
+- int rgbidx;
+
+ if (var->xres < MIN_XRES)
+ var->xres = MIN_XRES;
+@@ -165,27 +190,39 @@ imxfb_check_var(struct fb_var_screeninfo
+ var->xres_virtual = max(var->xres_virtual, var->xres);
+ var->yres_virtual = max(var->yres_virtual, var->yres);
+
++ memset(&var->transp, 0, sizeof(var->transp));
++
+ pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
+ switch (var->bits_per_pixel) {
+- case 16:
+- rgbidx = RGB_16;
+- break;
+ case 8:
+- rgbidx = RGB_8;
++ var->red.length = var->bits_per_pixel;
++ var->red.offset = 0;
++ var->green.length = var->bits_per_pixel;
++ var->green.offset = 0;
++ var->blue.length = var->bits_per_pixel;
++ var->blue.offset = 0;
++ break;
++ case 16:
++ if (fbi->pcr & PCR_TFT) {
++ var->red.length = 5;
++ var->red.offset = 11;
++ var->green.length = 6;
++ var->green.offset = 5;
++ var->blue.length = 5;
++ var->blue.offset = 0;
++ } else {
++ var->red.length = 4;
++ var->red.offset = 8;
++ var->green.length = 4;
++ var->green.offset = 4;
++ var->blue.length = 4;
++ var->blue.offset = 0;
++ }
+ break;
+ default:
+- rgbidx = RGB_16;
++ return -EINVAL;
+ }
+
+- /*
+- * Copy the RGB parameters for this display
+- * from the machine specific parameters.
+- */
+- var->red = fbi->rgb[rgbidx]->red;
+- var->green = fbi->rgb[rgbidx]->green;
+- var->blue = fbi->rgb[rgbidx]->blue;
+- var->transp = fbi->rgb[rgbidx]->transp;
+-
+ pr_debug("RGBT length = %d:%d:%d:%d\n",
+ var->red.length, var->green.length, var->blue.length,
+ var->transp.length);
+@@ -248,10 +285,11 @@ static void imxfb_enable_controller(stru
+
+ LCDC_RMCR = RMCR_LCDC_EN;
+
+- if(fbi->backlight_power)
+- fbi->backlight_power(1);
+ if(fbi->lcd_power)
+ fbi->lcd_power(1);
++ /* enable backlight after LCD */
++ if(fbi->backlight_power)
++ fbi->backlight_power(1);
+ }
+
+ static void imxfb_disable_controller(struct imxfb_info *fbi)
+@@ -312,6 +350,7 @@ static int imxfb_activate_var(struct fb_
+ pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
+ var->yres, var->vsync_len,
+ var->upper_margin, var->lower_margin);
++ pr_debug("var: bpp=%d\n", var->bits_per_pixel);
+
+ #if DEBUG_VAR
+ if (var->xres < 16 || var->xres > 1024)
+@@ -349,7 +388,17 @@ static int imxfb_activate_var(struct fb_
+ VCR_V_WAIT_2(var->lower_margin);
+
+ LCDC_SIZE = SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres);
+- LCDC_PCR = fbi->pcr;
++ // On TFT LCD i.MXL can support 16, 12, 8, 4bpp with the same hardware interface (12 to 16 bits)
++ // So if userspace app wants a 8bpp screen switch to 8bpp (can save ressources, with SDL for ex)
++ if( (var->bits_per_pixel == 8) && (fbi->pcr & PCR_TFT) )
++ {
++ pr_debug("Switching imxfb to 8bpp\n");
++ LCDC_PCR = (fbi->pcr & (~PCR_BPIX_MASK)) | PCR_BPIX_8 | PCR_END_BYTE_SWAP;
++ }
++ else
++ LCDC_PCR = fbi->pcr;
++
++ LCDC_VPW = VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4);
+ LCDC_PWMR = fbi->pwmr;
+ LCDC_LSCR1 = fbi->lscr1;
+ LCDC_DMACR = fbi->dmacr;
+@@ -391,7 +440,26 @@ static void imxfb_setup_gpio(struct imxf
+ case 1:
+ imx_gpio_mode(PD15_PF_LD0);
+ }
++#ifdef CONFIG_MACH_APF9328
++ /* initialize standard GPIOs */
++ imx_gpio_mode(PD6_PF_LSCLK);
++ imx_gpio_mode(PD14_PF_FLM_VSYNC);
++ imx_gpio_mode(PD13_PF_LP_HSYNC);
++// imx_gpio_mode(PD12_PF_ACD_OE);
+
++ /* if != 0 */
++ if( fbi->pwmr ) {
++ imx_gpio_mode(PD11_PF_CONTRAST);
++ }
++
++ /* sharp display specific */
++ if( fbi->pcr & PCR_SHARP ) {
++ imx_gpio_mode(PD10_PF_SPL_SPR);
++ imx_gpio_mode(PD7_PF_REV);
++ imx_gpio_mode(PD8_PF_CLS);
++ imx_gpio_mode(PD9_PF_PS);
++ }
++#else
+ /* initialize GPIOs */
+ imx_gpio_mode(PD6_PF_LSCLK);
+ imx_gpio_mode(PD11_PF_CONTRAST);
+@@ -406,6 +474,7 @@ static void imxfb_setup_gpio(struct imxf
+ imx_gpio_mode(PD9_PF_PS);
+ imx_gpio_mode(PD10_PF_SPL_SPR);
+ }
++#endif //CONFIG_MACH_APF9328
+ }
+
+ #ifdef CONFIG_PM
+@@ -469,9 +538,6 @@ static int __init imxfb_init_fbinfo(stru
+ info->fbops = &imxfb_ops;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+- fbi->rgb[RGB_16] = &def_rgb_16;
+- fbi->rgb[RGB_8] = &def_rgb_8;
+-
+ fbi->max_xres = inf->xres;
+ info->var.xres = inf->xres;
+ info->var.xres_virtual = inf->xres;
+Index: drivers/video/imxfb.h
+===================================================================
+--- a/drivers/video/imxfb.h
++++ b//dev/null
+@@ -1,73 +0,0 @@
+-/*
+- * linux/drivers/video/imxfb.h
+- *
+- * Freescale i.MX Frame Buffer device driver
+- *
+- * Copyright (C) 2004 S.Hauer, Pengutronix
+- *
+- * Copyright (C) 1999 Eric A. Thomas
+- * Based on acornfb.c Copyright (C) Russell King.
+- *
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License. See the file COPYING in the main directory of this archive
+- * for more details.
+- */
+-
+-/*
+- * These are the bitfields for each
+- * display depth that we support.
+- */
+-struct imxfb_rgb {
+- struct fb_bitfield red;
+- struct fb_bitfield green;
+- struct fb_bitfield blue;
+- struct fb_bitfield transp;
+-};
+-
+-#define RGB_16 (0)
+-#define RGB_8 (1)
+-#define NR_RGB 2
+-
+-struct imxfb_info {
+- struct device *dev;
+- struct imxfb_rgb *rgb[NR_RGB];
+-
+- u_int max_bpp;
+- u_int max_xres;
+- u_int max_yres;
+-
+- /*
+- * These are the addresses we mapped
+- * the framebuffer memory region to.
+- */
+- dma_addr_t map_dma;
+- u_char * map_cpu;
+- u_int map_size;
+-
+- u_char * screen_cpu;
+- dma_addr_t screen_dma;
+- u_int palette_size;
+-
+- dma_addr_t dbar1;
+- dma_addr_t dbar2;
+-
+- u_int pcr;
+- u_int pwmr;
+- u_int lscr1;
+- u_int dmacr;
+- u_int cmap_inverse:1,
+- cmap_static:1,
+- unused:30;
+-
+- void (*lcd_power)(int);
+- void (*backlight_power)(int);
+-};
+-
+-#define IMX_NAME "IMX"
+-
+-/*
+- * Minimum X and Y resolutions
+- */
+-#define MIN_XRES 64
+-#define MIN_YRES 64
+-
Deleted: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff 2008-07-28 14:12:20 UTC (rev 859)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff 2008-07-28 14:23:47 UTC (rev 860)
@@ -1,291 +0,0 @@
---- linux-2.6.23/drivers/video/imxfb.c 2006-09-20 05:42:06.000000000 +0200
-+++ linux-2.6.23-imx/drivers/video/imxfb.c 2006-10-01 14:22:39.000000000 +0200
-18:43:44.000000000 +0200
-+++ imxfb.c 2008-01-15 01:50:45.000000000 +0100
-@@ -42,22 +42,48 @@
- */
- #define DEBUG_VAR 1
-
--#include "imxfb.h"
-+struct imxfb_info {
-+ struct device *dev;
-
--static struct imxfb_rgb def_rgb_16 = {
-- .red = { .offset = 8, .length = 4, },
-- .green = { .offset = 4, .length = 4, },
-- .blue = { .offset = 0, .length = 4, },
-- .transp = { .offset = 0, .length = 0, },
--};
-+ u_int max_bpp;
-+ u_int max_xres;
-+ u_int max_yres;
-+
-+ /*
-+ * These are the addresses we mapped
-+ * the framebuffer memory region to.
-+ */
-+ dma_addr_t map_dma;
-+ u_char * map_cpu;
-+ u_int map_size;
-+
-+ u_char * screen_cpu;
-+ dma_addr_t screen_dma;
-+ u_int palette_size;
-+
-+ dma_addr_t dbar1;
-+ dma_addr_t dbar2;
-+
-+ u_int pcr;
-+ u_int pwmr;
-+ u_int lscr1;
-+ u_int dmacr;
-+ u_int cmap_inverse:1,
-+ cmap_static:1,
-+ unused:30;
-
--static struct imxfb_rgb def_rgb_8 = {
-- .red = { .offset = 0, .length = 8, },
-- .green = { .offset = 0, .length = 8, },
-- .blue = { .offset = 0, .length = 8, },
-- .transp = { .offset = 0, .length = 0, },
-+ void (*lcd_power)(int);
-+ void (*backlight_power)(int);
- };
-
-+#define IMX_NAME "IMX"
-+
-+/*
-+ * Minimum X and Y resolutions
-+ */
-+#define MIN_XRES 64
-+#define MIN_YRES 64
-+
- static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info);
-
- static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
-@@ -152,7 +178,6 @@ static int
- imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
- {
- struct imxfb_info *fbi = info->par;
-- int rgbidx;
-
- if (var->xres < MIN_XRES)
- var->xres = MIN_XRES;
-@@ -165,27 +190,39 @@ imxfb_check_var(struct fb_var_screeninfo
- var->xres_virtual = max(var->xres_virtual, var->xres);
- var->yres_virtual = max(var->yres_virtual, var->yres);
-
-+ memset(&var->transp, 0, sizeof(var->transp));
-+
- pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
- switch (var->bits_per_pixel) {
-- case 16:
-- rgbidx = RGB_16;
-- break;
- case 8:
-- rgbidx = RGB_8;
-+ var->red.length = var->bits_per_pixel;
-+ var->red.offset = 0;
-+ var->green.length = var->bits_per_pixel;
-+ var->green.offset = 0;
-+ var->blue.length = var->bits_per_pixel;
-+ var->blue.offset = 0;
-+ break;
-+ case 16:
-+ if (fbi->pcr & PCR_TFT) {
-+ var->red.length = 5;
-+ var->red.offset = 11;
-+ var->green.length = 6;
-+ var->green.offset = 5;
-+ var->blue.length = 5;
-+ var->blue.offset = 0;
-+ } else {
-+ var->red.length = 4;
-+ var->red.offset = 8;
-+ var->green.length = 4;
-+ var->green.offset = 4;
-+ var->blue.length = 4;
-+ var->blue.offset = 0;
-+ }
- break;
- default:
-- rgbidx = RGB_16;
-+ return -EINVAL;
- }
-
-- /*
-- * Copy the RGB parameters for this display
-- * from the machine specific parameters.
-- */
-- var->red = fbi->rgb[rgbidx]->red;
-- var->green = fbi->rgb[rgbidx]->green;
-- var->blue = fbi->rgb[rgbidx]->blue;
-- var->transp = fbi->rgb[rgbidx]->transp;
--
- pr_debug("RGBT length = %d:%d:%d:%d\n",
- var->red.length, var->green.length, var->blue.length,
- var->transp.length);
-@@ -248,10 +285,11 @@ static void imxfb_enable_controller(stru
-
- LCDC_RMCR = RMCR_LCDC_EN;
-
-- if(fbi->backlight_power)
-- fbi->backlight_power(1);
- if(fbi->lcd_power)
- fbi->lcd_power(1);
-+ /* enable backlight after LCD */
-+ if(fbi->backlight_power)
-+ fbi->backlight_power(1);
- }
-
- static void imxfb_disable_controller(struct imxfb_info *fbi)
-@@ -312,6 +350,7 @@ static int imxfb_activate_var(struct fb_
- pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",
- var->yres, var->vsync_len,
- var->upper_margin, var->lower_margin);
-+ pr_debug("var: bpp=%d\n", var->bits_per_pixel);
-
- #if DEBUG_VAR
- if (var->xres < 16 || var->xres > 1024)
-@@ -349,7 +388,17 @@ static int imxfb_activate_var(struct fb_
- VCR_V_WAIT_2(var->lower_margin);
-
- LCDC_SIZE = SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres);
-- LCDC_PCR = fbi->pcr;
-+ // On TFT LCD i.MXL can support 16, 12, 8, 4bpp with the same hardware interface (12 to 16 bits)
-+ // So if userspace app wants a 8bpp screen switch to 8bpp (can save ressources, with SDL for ex)
-+ if( (var->bits_per_pixel == 8) && (fbi->pcr & PCR_TFT) )
-+ {
-+ pr_debug("Switching imxfb to 8bpp\n");
-+ LCDC_PCR = (fbi->pcr & (~PCR_BPIX_MASK)) | PCR_BPIX_8 | PCR_END_BYTE_SWAP;
-+ }
-+ else
-+ LCDC_PCR = fbi->pcr;
-+
-+ LCDC_VPW = VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4);
- LCDC_PWMR = fbi->pwmr;
- LCDC_LSCR1 = fbi->lscr1;
- LCDC_DMACR = fbi->dmacr;
-@@ -391,7 +440,26 @@ static void imxfb_setup_gpio(struct imxf
- case 1:
- imx_gpio_mode(PD15_PF_LD0);
- }
-+#ifdef CONFIG_MACH_APF9328
-+ /* initialize standard GPIOs */
-+ imx_gpio_mode(PD6_PF_LSCLK);
-+ imx_gpio_mode(PD14_PF_FLM_VSYNC);
-+ imx_gpio_mode(PD13_PF_LP_HSYNC);
-+// imx_gpio_mode(PD12_PF_ACD_OE);
-
-+ /* if != 0 */
-+ if( fbi->pwmr ) {
-+ imx_gpio_mode(PD11_PF_CONTRAST);
-+ }
-+
-+ /* sharp display specific */
-+ if( fbi->pcr & PCR_SHARP ) {
-+ imx_gpio_mode(PD10_PF_SPL_SPR);
-+ imx_gpio_mode(PD7_PF_REV);
-+ imx_gpio_mode(PD8_PF_CLS);
-+ imx_gpio_mode(PD9_PF_PS);
-+ }
-+#else
- /* initialize GPIOs */
- imx_gpio_mode(PD6_PF_LSCLK);
- imx_gpio_mode(PD11_PF_CONTRAST);
-@@ -406,6 +474,7 @@ static void imxfb_setup_gpio(struct imxf
- imx_gpio_mode(PD9_PF_PS);
- imx_gpio_mode(PD10_PF_SPL_SPR);
- }
-+#endif //CONFIG_MACH_APF9328
- }
-
- #ifdef CONFIG_PM
-@@ -469,9 +538,6 @@ static int __init imxfb_init_fbinfo(stru
- info->fbops = &imxfb_ops;
- info->flags = FBINFO_FLAG_DEFAULT;
-
-- fbi->rgb[RGB_16] = &def_rgb_16;
-- fbi->rgb[RGB_8] = &def_rgb_8;
--
- fbi->max_xres = inf->xres;
- info->var.xres = inf->xres;
- info->var.xres_virtual = inf->xres;
-Index: drivers/video/imxfb.h
-===================================================================
---- a/drivers/video/imxfb.h
-+++ b//dev/null
-@@ -1,73 +0,0 @@
--/*
-- * linux/drivers/video/imxfb.h
-- *
-- * Freescale i.MX Frame Buffer device driver
-- *
-- * Copyright (C) 2004 S.Hauer, Pengutronix
-- *
-- * Copyright (C) 1999 Eric A. Thomas
-- * Based on acornfb.c Copyright (C) Russell King.
-- *
-- * This file is subject to the terms and conditions of the GNU General Public
-- * License. See the file COPYING in the main directory of this archive
-- * for more details.
-- */
--
--/*
-- * These are the bitfields for each
-- * display depth that we support.
-- */
--struct imxfb_rgb {
-- struct fb_bitfield red;
-- struct fb_bitfield green;
-- struct fb_bitfield blue;
-- struct fb_bitfield transp;
--};
--
--#define RGB_16 (0)
--#define RGB_8 (1)
--#define NR_RGB 2
--
--struct imxfb_info {
-- struct device *dev;
-- struct imxfb_rgb *rgb[NR_RGB];
--
-- u_int max_bpp;
-- u_int max_xres;
-- u_int max_yres;
--
-- /*
-- * These are the addresses we mapped
-- * the framebuffer memory region to.
-- */
-- dma_addr_t map_dma;
-- u_char * map_cpu;
-- u_int map_size;
--
-- u_char * screen_cpu;
-- dma_addr_t screen_dma;
-- u_int palette_size;
--
-- dma_addr_t dbar1;
-- dma_addr_t dbar2;
--
-- u_int pcr;
-- u_int pwmr;
-- u_int lscr1;
-- u_int dmacr;
-- u_int cmap_inverse:1,
-- cmap_static:1,
-- unused:30;
--
-- void (*lcd_power)(int);
-- void (*backlight_power)(int);
--};
--
--#define IMX_NAME "IMX"
--
--/*
-- * Minimum X and Y resolutions
-- */
--#define MIN_XRES 64
--#define MIN_YRES 64
--
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-07-28 14:12:12
|
Revision: 859
http://armadeus.svn.sourceforge.net/armadeus/?rev=859&view=rev
Author: artemys
Date: 2008-07-28 14:12:20 +0000 (Mon, 28 Jul 2008)
Log Message:
-----------
[LINUX] Split 013-framebuffer patch in 2
Modified Paths:
--------------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff
Added Paths:
-----------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/014-imxregs-add-lcd-bpix-mask.diff
Modified: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff 2008-07-25 16:08:45 UTC (rev 858)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff 2008-07-28 14:12:20 UTC (rev 859)
@@ -289,13 +289,3 @@
-#define MIN_XRES 64
-#define MIN_YRES 64
-
---- linux-2.6.18.1/include/asm-arm/arch-imx/imx-regs.h 2007-04-05 22:31:12.000000000 +0200
-+++ linux-2.6.18.1.fb8bits/include/asm-arm/arch-imx/imx-regs.h 2007-05-08 12:38:19.000000000 +0200
-@@ -411,6 +411,7 @@
- #define PCR_BPIX_8 (3<<25)
- #define PCR_BPIX_12 (4<<25)
- #define PCR_BPIX_16 (4<<25)
-+#define PCR_BPIX_MASK (7<<25)
- #define PCR_PIXPOL (1<<24)
- #define PCR_FLMPOL (1<<23)
- #define PCR_LPPOL (1<<22)
Added: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/014-imxregs-add-lcd-bpix-mask.diff
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/014-imxregs-add-lcd-bpix-mask.diff (rev 0)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/014-imxregs-add-lcd-bpix-mask.diff 2008-07-28 14:12:20 UTC (rev 859)
@@ -0,0 +1,10 @@
+--- linux-2.6.23.1/include/asm-arm/arch-imx/imx-regs.h 2007-04-05 22:31:12.000000000 +0200
++++ linux-2.6.23.1.mod/include/asm-arm/arch-imx/imx-regs.h 2007-05-08 12:38:19.000000000 +0200
+@@ -411,6 +411,7 @@
+ #define PCR_BPIX_8 (3<<25)
+ #define PCR_BPIX_12 (4<<25)
+ #define PCR_BPIX_16 (4<<25)
++#define PCR_BPIX_MASK (7<<25)
+ #define PCR_PIXPOL (1<<24)
+ #define PCR_FLMPOL (1<<23)
+ #define PCR_LPPOL (1<<22)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ar...@us...> - 2008-07-25 16:08:36
|
Revision: 858
http://armadeus.svn.sourceforge.net/armadeus/?rev=858&view=rev
Author: artemys
Date: 2008-07-25 16:08:45 +0000 (Fri, 25 Jul 2008)
Log Message:
-----------
[LINUX] Split framebuff patch in 2: imxfb & logo
Modified Paths:
--------------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff
Added Paths:
-----------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/015-logo-add-armadeus-project-tux.diff
Modified: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff 2008-07-25 15:56:57 UTC (rev 857)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/013-linux-2.6.23.1-framebuff.diff 2008-07-25 16:08:45 UTC (rev 858)
@@ -299,19257 +299,3 @@
#define PCR_PIXPOL (1<<24)
#define PCR_FLMPOL (1<<23)
#define PCR_LPPOL (1<<22)
---- linux-2.6.23/drivers/video/logo/Kconfig 2006-09-20 05:42:06.000000000 +0200
-+++ linux-2.6.23-imx/drivers/video/logo/Kconfig 2006-10-01 14:22:39.000000000 +0200
-@@ -70,5 +70,12 @@ config LOGO_M32R_CLUT224
- depends on M32R
- default y
-
-+config LOGO_ARMADEUS_CLUT224
-+ bool "224-color Armadeus Linux logo"
-+ depends on ARM
-+ default y
-+ help
-+ Choose this if you want to have the Armadeus Tux as boot logo
-+
- endif # LOGO
-
---- linux-2.6.23/drivers/video/logo/logo_armadeus_clut224.ppm 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.23-imx/drivers/video/logo/logo_armadeus_clut224.ppm 2006-10-01 14:22:39.000000000 +0200
-@@ -0,0 +1,19205 @@
-+P3
-+# CREATOR: The GIMP's PNM Filter Version 1.0
-+# Armadeus project 224 colors Tux logo
-+80 80
-+255
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+6
-+6
-+6
-+10
-+10
-+10
-+10
-+10
-+10
-+10
-+10
-+10
-+6
-+6
-+6
-+6
-+6
-+6
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+10
-+10
-+10
-+14
-+14
-+14
-+22
-+22
-+22
-+26
-+26
-+26
-+30
-+30
-+30
-+34
-+34
-+34
-+30
-+30
-+30
-+30
-+30
-+30
-+26
-+26
-+26
-+18
-+18
-+18
-+14
-+14
-+14
-+10
-+10
-+10
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+14
-+14
-+14
-+26
-+26
-+26
-+42
-+42
-+42
-+54
-+54
-+54
-+66
-+66
-+66
-+78
-+78
-+78
-+78
-+78
-+78
-+78
-+78
-+78
-+74
-+74
-+74
-+66
-+66
-+66
-+54
-+54
-+54
-+42
-+42
-+42
-+26
-+26
-+26
-+18
-+18
-+18
-+10
-+10
-+10
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+22
-+22
-+22
-+42
-+42
-+42
-+66
-+66
-+66
-+86
-+86
-+86
-+66
-+66
-+66
-+38
-+38
-+38
-+38
-+38
-+38
-+22
-+22
-+22
-+26
-+26
-+26
-+34
-+34
-+34
-+54
-+54
-+54
-+66
-+66
-+66
-+86
-+86
-+86
-+70
-+70
-+70
-+46
-+46
-+46
-+26
-+26
-+26
-+14
-+14
-+14
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+26
-+26
-+26
-+50
-+50
-+50
-+82
-+82
-+82
-+58
-+58
-+58
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+54
-+54
-+54
-+86
-+86
-+86
-+66
-+66
-+66
-+38
-+38
-+38
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+22
-+22
-+22
-+50
-+50
-+50
-+78
-+78
-+78
-+34
-+34
-+34
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+70
-+70
-+70
-+78
-+78
-+78
-+46
-+46
-+46
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+18
-+18
-+18
-+42
-+42
-+42
-+82
-+82
-+82
-+26
-+26
-+26
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+14
-+14
-+14
-+46
-+46
-+46
-+34
-+34
-+34
-+6
-+6
-+6
-+2
-+2
-+6
-+42
-+42
-+42
-+78
-+78
-+78
-+42
-+42
-+42
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+30
-+30
-+30
-+66
-+66
-+66
-+58
-+58
-+58
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+26
-+26
-+26
-+86
-+86
-+86
-+101
-+101
-+101
-+46
-+46
-+46
-+10
-+10
-+10
-+2
-+2
-+6
-+58
-+58
-+58
-+70
-+70
-+70
-+34
-+34
-+34
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+42
-+42
-+42
-+86
-+86
-+86
-+10
-+10
-+10
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+30
-+30
-+30
-+94
-+94
-+94
-+94
-+94
-+94
-+58
-+58
-+58
-+26
-+26
-+26
-+2
-+2
-+6
-+6
-+6
-+6
-+78
-+78
-+78
-+54
-+54
-+54
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+22
-+22
-+22
-+62
-+62
-+62
-+62
-+62
-+62
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+26
-+26
-+26
-+54
-+54
-+54
-+38
-+38
-+38
-+18
-+18
-+18
-+10
-+10
-+10
-+2
-+2
-+6
-+2
-+2
-+6
-+34
-+34
-+34
-+82
-+82
-+82
-+38
-+38
-+38
-+14
-+14
-+14
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+30
-+30
-+30
-+78
-+78
-+78
-+30
-+30
-+30
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+10
-+10
-+10
-+10
-+10
-+10
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+78
-+78
-+78
-+50
-+50
-+50
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+38
-+38
-+38
-+86
-+86
-+86
-+14
-+14
-+14
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+54
-+54
-+54
-+66
-+66
-+66
-+26
-+26
-+26
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+42
-+42
-+42
-+82
-+82
-+82
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+10
-+10
-+10
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+14
-+14
-+14
-+10
-+10
-+10
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+18
-+18
-+18
-+82
-+82
-+82
-+34
-+34
-+34
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+46
-+46
-+46
-+86
-+86
-+86
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+6
-+6
-+6
-+22
-+22
-+22
-+34
-+34
-+34
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+18
-+18
-+18
-+34
-+34
-+34
-+10
-+10
-+10
-+50
-+50
-+50
-+22
-+22
-+22
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+10
-+10
-+10
-+86
-+86
-+86
-+42
-+42
-+42
-+14
-+14
-+14
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+46
-+46
-+46
-+86
-+86
-+86
-+2
-+2
-+6
-+2
-+2
-+6
-+38
-+38
-+38
-+116
-+116
-+116
-+94
-+94
-+94
-+22
-+22
-+22
-+22
-+22
-+22
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+14
-+14
-+14
-+86
-+86
-+86
-+137
-+137
-+137
-+161
-+161
-+161
-+154
-+153
-+152
-+38
-+38
-+38
-+26
-+26
-+26
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+86
-+86
-+86
-+46
-+46
-+46
-+14
-+14
-+14
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+46
-+46
-+46
-+86
-+86
-+86
-+2
-+2
-+6
-+14
-+14
-+14
-+134
-+134
-+134
-+198
-+198
-+198
-+195
-+195
-+195
-+116
-+116
-+116
-+10
-+10
-+10
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+101
-+98
-+89
-+187
-+187
-+187
-+210
-+210
-+210
-+218
-+218
-+218
-+214
-+214
-+214
-+134
-+134
-+134
-+14
-+14
-+14
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+86
-+86
-+86
-+50
-+50
-+50
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+46
-+46
-+46
-+86
-+86
-+86
-+2
-+2
-+6
-+54
-+54
-+54
-+218
-+218
-+218
-+195
-+195
-+195
-+226
-+226
-+226
-+246
-+246
-+246
-+58
-+58
-+58
-+2
-+2
-+6
-+2
-+2
-+6
-+30
-+30
-+30
-+210
-+210
-+210
-+253
-+253
-+253
-+173
-+173
-+172
-+123
-+123
-+123
-+221
-+221
-+221
-+234
-+234
-+234
-+74
-+74
-+74
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+70
-+70
-+70
-+58
-+58
-+58
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+46
-+46
-+46
-+82
-+82
-+82
-+2
-+2
-+6
-+106
-+106
-+106
-+171
-+171
-+170
-+26
-+26
-+26
-+86
-+86
-+86
-+226
-+226
-+226
-+123
-+123
-+123
-+10
-+10
-+10
-+14
-+14
-+14
-+46
-+46
-+46
-+231
-+231
-+231
-+190
-+190
-+190
-+6
-+6
-+6
-+70
-+70
-+70
-+90
-+90
-+90
-+238
-+238
-+238
-+159
-+158
-+157
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+70
-+70
-+70
-+58
-+58
-+58
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+42
-+42
-+42
-+86
-+86
-+86
-+6
-+6
-+6
-+116
-+116
-+116
-+106
-+106
-+106
-+6
-+6
-+6
-+70
-+70
-+70
-+147
-+147
-+147
-+127
-+127
-+127
-+18
-+18
-+18
-+38
-+38
-+38
-+54
-+54
-+54
-+221
-+221
-+221
-+106
-+106
-+106
-+2
-+2
-+6
-+14
-+14
-+14
-+46
-+46
-+46
-+190
-+190
-+190
-+198
-+198
-+198
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+74
-+74
-+74
-+62
-+62
-+62
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+42
-+42
-+42
-+94
-+94
-+94
-+14
-+14
-+14
-+101
-+101
-+101
-+127
-+127
-+127
-+2
-+2
-+6
-+18
-+18
-+18
-+116
-+116
-+116
-+130
-+98
-+46
-+121
-+92
-+8
-+121
-+92
-+8
-+100
-+78
-+10
-+161
-+161
-+161
-+106
-+106
-+106
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+195
-+195
-+195
-+195
-+195
-+195
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+74
-+74
-+74
-+62
-+62
-+62
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+1
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+38
-+38
-+38
-+90
-+90
-+90
-+14
-+14
-+14
-+58
-+58
-+58
-+210
-+210
-+210
-+26
-+26
-+26
-+52
-+36
-+6
-+155
-+116
-+10
-+226
-+170
-+11
-+236
-+186
-+11
-+225
-+175
-+15
-+184
-+144
-+12
-+215
-+174
-+15
-+182
-+146
-+52
-+37
-+28
-+9
-+2
-+2
-+6
-+70
-+70
-+70
-+246
-+246
-+246
-+137
-+137
-+137
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+70
-+70
-+70
-+66
-+66
-+66
-+26
-+26
-+26
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+38
-+38
-+38
-+86
-+86
-+86
-+14
-+14
-+14
-+10
-+10
-+10
-+195
-+195
-+195
-+203
-+179
-+129
-+192
-+133
-+9
-+225
-+175
-+15
-+239
-+182
-+13
-+236
-+190
-+10
-+232
-+195
-+16
-+232
-+200
-+30
-+245
-+216
-+46
-+241
-+208
-+19
-+232
-+195
-+16
-+184
-+144
-+12
-+203
-+179
-+129
-+211
-+206
-+186
-+42
-+42
-+42
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+50
-+50
-+50
-+74
-+74
-+74
-+30
-+30
-+30
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+34
-+34
-+34
-+86
-+86
-+86
-+14
-+14
-+14
-+2
-+2
-+6
-+121
-+87
-+25
-+192
-+133
-+9
-+219
-+162
-+10
-+239
-+182
-+13
-+236
-+186
-+11
-+232
-+195
-+16
-+241
-+208
-+19
-+245
-+216
-+46
-+245
-+216
-+46
-+245
-+216
-+46
-+246
-+215
-+20
-+241
-+208
-+19
-+241
-+208
-+19
-+226
-+184
-+13
-+121
-+87
-+25
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+50
-+50
-+50
-+82
-+82
-+82
-+34
-+34
-+34
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+34
-+34
-+34
-+82
-+82
-+82
-+30
-+30
-+30
-+61
-+42
-+6
-+180
-+123
-+7
-+206
-+145
-+10
-+230
-+174
-+11
-+239
-+182
-+13
-+236
-+190
-+10
-+238
-+202
-+15
-+241
-+208
-+19
-+237
-+201
-+75
-+245
-+216
-+46
-+246
-+215
-+20
-+246
-+215
-+20
-+246
-+215
-+20
-+226
-+184
-+13
-+215
-+174
-+15
-+184
-+144
-+12
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+26
-+26
-+26
-+94
-+94
-+94
-+42
-+42
-+42
-+14
-+14
-+14
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+30
-+30
-+30
-+78
-+78
-+78
-+50
-+50
-+50
-+104
-+69
-+6
-+192
-+133
-+9
-+216
-+158
-+10
-+236
-+178
-+12
-+236
-+186
-+11
-+232
-+195
-+16
-+241
-+208
-+19
-+245
-+216
-+46
-+245
-+216
-+46
-+246
-+215
-+20
-+246
-+215
-+20
-+241
-+208
-+19
-+198
-+155
-+10
-+200
-+144
-+11
-+216
-+158
-+10
-+155
-+116
-+10
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+90
-+90
-+90
-+54
-+54
-+54
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+30
-+30
-+30
-+78
-+78
-+78
-+46
-+46
-+46
-+22
-+22
-+22
-+137
-+92
-+6
-+210
-+164
-+10
-+239
-+182
-+13
-+236
-+190
-+10
-+238
-+202
-+15
-+241
-+208
-+19
-+246
-+215
-+20
-+246
-+215
-+20
-+241
-+208
-+19
-+210
-+164
-+10
-+185
-+133
-+11
-+210
-+150
-+10
-+216
-+158
-+10
-+210
-+150
-+10
-+100
-+78
-+10
-+2
-+2
-+6
-+6
-+6
-+6
-+54
-+54
-+54
-+14
-+14
-+14
-+2
-+2
-+6
-+2
-+2
-+6
-+62
-+62
-+62
-+74
-+74
-+74
-+30
-+30
-+30
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+34
-+34
-+34
-+78
-+78
-+78
-+50
-+50
-+50
-+6
-+6
-+6
-+80
-+60
-+22
-+139
-+102
-+15
-+190
-+146
-+13
-+226
-+184
-+13
-+232
-+200
-+30
-+232
-+195
-+16
-+215
-+174
-+15
-+190
-+146
-+13
-+168
-+122
-+10
-+192
-+133
-+9
-+210
-+150
-+10
-+213
-+154
-+11
-+202
-+158
-+25
-+168
-+150
-+104
-+101
-+98
-+89
-+2
-+2
-+6
-+2
-+2
-+6
-+78
-+78
-+78
-+116
-+116
-+116
-+58
-+58
-+58
-+2
-+2
-+6
-+22
-+22
-+22
-+90
-+90
-+90
-+46
-+46
-+46
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+38
-+38
-+38
-+86
-+86
-+86
-+50
-+50
-+50
-+6
-+6
-+6
-+127
-+127
-+127
-+168
-+150
-+104
-+156
-+107
-+11
-+168
-+122
-+10
-+198
-+155
-+10
-+184
-+144
-+12
-+197
-+138
-+11
-+200
-+144
-+11
-+206
-+145
-+10
-+206
-+145
-+10
-+197
-+138
-+11
-+203
-+179
-+129
-+195
-+195
-+195
-+198
-+198
-+198
-+173
-+173
-+172
-+14
-+14
-+14
-+2
-+2
-+6
-+22
-+22
-+22
-+116
-+116
-+116
-+116
-+116
-+116
-+22
-+22
-+22
-+2
-+2
-+6
-+74
-+74
-+74
-+70
-+70
-+70
-+30
-+30
-+30
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+18
-+18
-+18
-+50
-+50
-+50
-+101
-+101
-+101
-+26
-+26
-+26
-+10
-+10
-+10
-+137
-+137
-+137
-+190
-+190
-+190
-+168
-+150
-+104
-+156
-+107
-+11
-+197
-+138
-+11
-+200
-+144
-+11
-+197
-+138
-+11
-+192
-+133
-+9
-+180
-+123
-+7
-+190
-+142
-+34
-+203
-+179
-+129
-+187
-+187
-+187
-+202
-+202
-+202
-+221
-+221
-+221
-+214
-+214
-+214
-+66
-+66
-+66
-+2
-+2
-+6
-+2
-+2
-+6
-+50
-+50
-+50
-+62
-+62
-+62
-+6
-+6
-+6
-+2
-+2
-+6
-+10
-+10
-+10
-+90
-+90
-+90
-+50
-+50
-+50
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+34
-+34
-+34
-+74
-+74
-+74
-+74
-+74
-+74
-+2
-+2
-+6
-+6
-+6
-+6
-+144
-+144
-+144
-+198
-+198
-+198
-+190
-+190
-+190
-+170
-+164
-+156
-+154
-+121
-+60
-+156
-+107
-+11
-+156
-+107
-+11
-+168
-+124
-+44
-+168
-+150
-+104
-+187
-+187
-+187
-+190
-+190
-+190
-+210
-+210
-+210
-+246
-+246
-+246
-+253
-+253
-+253
-+253
-+253
-+253
-+182
-+182
-+182
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+62
-+62
-+62
-+74
-+74
-+74
-+34
-+34
-+34
-+14
-+14
-+14
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+22
-+22
-+22
-+54
-+54
-+54
-+94
-+94
-+94
-+18
-+18
-+18
-+2
-+2
-+6
-+46
-+46
-+46
-+234
-+234
-+234
-+221
-+221
-+221
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+187
-+187
-+187
-+187
-+187
-+187
-+190
-+190
-+190
-+190
-+190
-+190
-+195
-+195
-+195
-+214
-+214
-+214
-+242
-+242
-+242
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+82
-+82
-+82
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+14
-+14
-+14
-+86
-+86
-+86
-+54
-+54
-+54
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+18
-+18
-+18
-+46
-+46
-+46
-+90
-+90
-+90
-+46
-+46
-+46
-+18
-+18
-+18
-+6
-+6
-+6
-+182
-+182
-+182
-+253
-+253
-+253
-+246
-+246
-+246
-+206
-+206
-+206
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+190
-+206
-+206
-+206
-+231
-+231
-+231
-+250
-+250
-+250
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+202
-+202
-+202
-+14
-+14
-+14
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+42
-+42
-+42
-+86
-+86
-+86
-+42
-+42
-+42
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+14
-+14
-+14
-+38
-+38
-+38
-+74
-+74
-+74
-+66
-+66
-+66
-+2
-+2
-+6
-+6
-+6
-+6
-+90
-+90
-+90
-+250
-+250
-+250
-+253
-+253
-+253
-+253
-+253
-+253
-+238
-+238
-+238
-+198
-+198
-+198
-+190
-+190
-+190
-+190
-+190
-+190
-+195
-+195
-+195
-+221
-+221
-+221
-+246
-+246
-+246
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+82
-+82
-+82
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+78
-+78
-+78
-+70
-+70
-+70
-+34
-+34
-+34
-+14
-+14
-+14
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+34
-+34
-+34
-+66
-+66
-+66
-+78
-+78
-+78
-+6
-+6
-+6
-+2
-+2
-+6
-+18
-+18
-+18
-+218
-+218
-+218
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+246
-+246
-+246
-+226
-+226
-+226
-+231
-+231
-+231
-+246
-+246
-+246
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+179
-+179
-+178
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+18
-+18
-+18
-+90
-+90
-+90
-+62
-+62
-+62
-+30
-+30
-+30
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+26
-+26
-+26
-+58
-+58
-+58
-+90
-+90
-+90
-+18
-+18
-+18
-+2
-+2
-+6
-+2
-+2
-+6
-+111
-+111
-+110
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+250
-+250
-+250
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+231
-+231
-+231
-+18
-+18
-+18
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+18
-+18
-+18
-+94
-+94
-+94
-+54
-+54
-+54
-+26
-+26
-+26
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+22
-+22
-+22
-+50
-+50
-+50
-+90
-+90
-+90
-+26
-+26
-+26
-+2
-+2
-+6
-+2
-+2
-+6
-+14
-+14
-+14
-+195
-+195
-+195
-+250
-+250
-+250
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+250
-+250
-+250
-+242
-+242
-+242
-+54
-+54
-+54
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+38
-+38
-+38
-+86
-+86
-+86
-+50
-+50
-+50
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+14
-+14
-+14
-+38
-+38
-+38
-+82
-+82
-+82
-+34
-+34
-+34
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+42
-+42
-+42
-+195
-+195
-+195
-+246
-+246
-+246
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+250
-+250
-+250
-+242
-+242
-+242
-+242
-+242
-+242
-+250
-+250
-+250
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+250
-+250
-+250
-+246
-+246
-+246
-+238
-+238
-+238
-+226
-+226
-+226
-+231
-+231
-+231
-+101
-+101
-+101
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+38
-+38
-+38
-+82
-+82
-+82
-+42
-+42
-+42
-+14
-+14
-+14
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+26
-+26
-+26
-+62
-+62
-+62
-+66
-+66
-+66
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+70
-+70
-+70
-+171
-+171
-+170
-+206
-+206
-+206
-+234
-+234
-+234
-+246
-+246
-+246
-+250
-+250
-+250
-+250
-+250
-+250
-+238
-+238
-+238
-+226
-+226
-+226
-+231
-+231
-+231
-+238
-+238
-+238
-+250
-+250
-+250
-+250
-+250
-+250
-+250
-+250
-+250
-+246
-+246
-+246
-+231
-+231
-+231
-+214
-+214
-+214
-+206
-+206
-+206
-+202
-+202
-+202
-+202
-+202
-+202
-+198
-+198
-+198
-+202
-+202
-+202
-+182
-+182
-+182
-+18
-+18
-+18
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+62
-+62
-+62
-+66
-+66
-+66
-+30
-+30
-+30
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+42
-+42
-+42
-+82
-+82
-+82
-+18
-+18
-+18
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+10
-+10
-+10
-+94
-+94
-+94
-+182
-+182
-+182
-+218
-+218
-+218
-+242
-+242
-+242
-+250
-+250
-+250
-+253
-+253
-+253
-+253
-+253
-+253
-+250
-+250
-+250
-+234
-+234
-+234
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+246
-+246
-+246
-+238
-+238
-+238
-+226
-+226
-+226
-+210
-+210
-+210
-+202
-+202
-+202
-+195
-+195
-+195
-+195
-+195
-+195
-+210
-+210
-+210
-+159
-+158
-+157
-+6
-+6
-+6
-+14
-+14
-+14
-+50
-+50
-+50
-+14
-+14
-+14
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+86
-+86
-+86
-+46
-+46
-+46
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+22
-+22
-+22
-+54
-+54
-+54
-+70
-+70
-+70
-+2
-+2
-+6
-+2
-+2
-+6
-+10
-+10
-+10
-+2
-+2
-+6
-+22
-+22
-+22
-+169
-+169
-+168
-+231
-+231
-+231
-+250
-+250
-+250
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+250
-+250
-+250
-+242
-+242
-+242
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+246
-+246
-+246
-+231
-+231
-+231
-+206
-+206
-+206
-+198
-+198
-+198
-+226
-+226
-+226
-+94
-+94
-+94
-+2
-+2
-+6
-+6
-+6
-+6
-+38
-+38
-+38
-+30
-+30
-+30
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+62
-+62
-+62
-+66
-+66
-+66
-+26
-+26
-+26
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+30
-+30
-+30
-+74
-+74
-+74
-+50
-+50
-+50
-+2
-+2
-+6
-+26
-+26
-+26
-+26
-+26
-+26
-+2
-+2
-+6
-+106
-+106
-+106
-+238
-+238
-+238
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+246
-+246
-+246
-+218
-+218
-+218
-+202
-+202
-+202
-+210
-+210
-+210
-+14
-+14
-+14
-+2
-+2
-+6
-+2
-+2
-+6
-+30
-+30
-+30
-+22
-+22
-+22
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+18
-+18
-+18
-+86
-+86
-+86
-+42
-+42
-+42
-+14
-+14
-+14
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+14
-+14
-+14
-+42
-+42
-+42
-+90
-+90
-+90
-+22
-+22
-+22
-+2
-+2
-+6
-+42
-+42
-+42
-+2
-+2
-+6
-+18
-+18
-+18
-+218
-+218
-+218
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+250
-+250
-+250
-+221
-+221
-+221
-+218
-+218
-+218
-+101
-+101
-+101
-+2
-+2
-+6
-+14
-+14
-+14
-+18
-+18
-+18
-+38
-+38
-+38
-+10
-+10
-+10
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+78
-+78
-+78
-+58
-+58
-+58
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+18
-+18
-+18
-+54
-+54
-+54
-+82
-+82
-+82
-+2
-+2
-+6
-+26
-+26
-+26
-+22
-+22
-+22
-+2
-+2
-+6
-+123
-+123
-+123
-+253
-+253
-+253
-+253
-+253
-+253
-+252
-+252
-+252
-+240
-+240
-+239
-+216
-+215
-+215
-+161
-+161
-+161
-+106
-+105
-+104
-+66
-+66
-+66
-+44
-+43
-+41
-+34
-+33
-+31
-+38
-+37
-+36
-+56
-+55
-+54
-+84
-+83
-+82
-+130
-+130
-+129
-+182
-+182
-+182
-+217
-+217
-+217
-+237
-+237
-+237
-+252
-+252
-+252
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+250
-+250
-+250
-+238
-+238
-+238
-+198
-+198
-+198
-+6
-+6
-+6
-+38
-+38
-+38
-+58
-+58
-+58
-+26
-+26
-+26
-+38
-+38
-+38
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+46
-+46
-+46
-+78
-+78
-+78
-+30
-+30
-+30
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+30
-+30
-+30
-+74
-+74
-+74
-+58
-+58
-+58
-+2
-+2
-+6
-+42
-+42
-+42
-+2
-+2
-+6
-+22
-+22
-+22
-+231
-+231
-+231
-+252
-+252
-+252
-+240
-+240
-+239
-+182
-+182
-+182
-+111
-+111
-+110
-+46
-+46
-+46
-+26
-+25
-+23
-+26
-+25
-+23
-+25
-+24
-+22
-+25
-+24
-+22
-+25
-+24
-+22
-+25
-+24
-+22
-+25
-+24
-+22
-+25
-+24
-+22
-+26
-+25
-+23
-+26
-+25
-+23
-+49
-+48
-+47
-+106
-+106
-+106
-+192
-+192
-+192
-+249
-+249
-+249
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+246
-+246
-+246
-+46
-+46
-+46
-+38
-+38
-+38
-+42
-+42
-+42
-+14
-+14
-+14
-+38
-+38
-+38
-+14
-+14
-+14
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+86
-+86
-+86
-+46
-+46
-+46
-+14
-+14
-+14
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+14
-+14
-+14
-+42
-+42
-+42
-+90
-+90
-+90
-+18
-+18
-+18
-+18
-+18
-+18
-+26
-+26
-+26
-+2
-+2
-+6
-+116
-+116
-+116
-+251
-+251
-+251
-+217
-+216
-+216
-+123
-+123
-+123
-+44
-+43
-+41
-+26
-+25
-+23
-+26
-+25
-+23
-+25
-+24
-+22
-+28
-+27
-+25
-+33
-+32
-+30
-+36
-+35
-+33
-+36
-+35
-+33
-+35
-+34
-+32
-+32
-+31
-+28
-+29
-+28
-+27
-+26
-+25
-+23
-+26
-+25
-+23
-+26
-+25
-+23
-+26
-+25
-+23
-+87
-+86
-+84
-+217
-+216
-+216
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+94
-+94
-+94
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+10
-+10
-+10
-+34
-+34
-+34
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+74
-+74
-+74
-+58
-+58
-+58
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+26
-+26
-+26
-+66
-+66
-+66
-+82
-+82
-+82
-+2
-+2
-+6
-+38
-+38
-+38
-+6
-+6
-+6
-+14
-+14
-+14
-+206
-+206
-+206
-+196
-+196
-+195
-+84
-+83
-+82
-+27
-+26
-+24
-+26
-+25
-+23
-+26
-+25
-+23
-+34
-+33
-+31
-+56
-+55
-+54
-+95
-+95
-+93
-+135
-+135
-+134
-+157
-+157
-+157
-+160
-+160
-+159
-+154
-+153
-+152
-+130
-+130
-+129
-+100
-+99
-+98
-+66
-+66
-+66
-+56
-+55
-+54
-+46
-+45
-+44
-+33
-+32
-+30
-+46
-+46
-+46
-+160
-+160
-+159
-+248
-+248
-+248
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+144
-+144
-+144
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+46
-+46
-+46
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+42
-+42
-+42
-+74
-+74
-+74
-+30
-+30
-+30
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+14
-+14
-+14
-+42
-+42
-+42
-+90
-+90
-+90
-+26
-+26
-+26
-+6
-+6
-+6
-+42
-+42
-+42
-+2
-+2
-+6
-+74
-+74
-+74
-+184
-+184
-+184
-+60
-+59
-+56
-+26
-+25
-+23
-+26
-+25
-+23
-+29
-+28
-+27
-+60
-+59
-+56
-+127
-+127
-+127
-+217
-+217
-+217
-+253
-+253
-+253
-+245
-+245
-+245
-+252
-+252
-+252
-+253
-+253
-+253
-+253
-+253
-+253
-+217
-+216
-+216
-+190
-+190
-+189
-+208
-+207
-+207
-+212
-+212
-+212
-+184
-+184
-+184
-+130
-+130
-+129
-+50
-+50
-+50
-+88
-+88
-+86
-+217
-+217
-+217
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+182
-+182
-+182
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+46
-+46
-+46
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+10
-+10
-+10
-+86
-+86
-+86
-+38
-+38
-+38
-+10
-+10
-+10
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+26
-+26
-+26
-+66
-+66
-+66
-+82
-+82
-+82
-+2
-+2
-+6
-+22
-+22
-+22
-+18
-+18
-+18
-+2
-+2
-+6
-+147
-+147
-+147
-+100
-+99
-+98
-+26
-+25
-+23
-+26
-+25
-+23
-+29
-+28
-+27
-+79
-+79
-+77
-+181
-+181
-+180
-+251
-+251
-+251
-+248
-+248
-+248
-+198
-+198
-+197
-+130
-+130
-+129
-+198
-+198
-+197
-+253
-+253
-+253
-+252
-+252
-+252
-+115
-+114
-+113
-+35
-+34
-+32
-+111
-+111
-+110
-+231
-+231
-+230
-+253
-+253
-+253
-+218
-+218
-+218
-+66
-+66
-+66
-+35
-+34
-+32
-+161
-+161
-+161
-+249
-+249
-+249
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+206
-+206
-+206
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+38
-+38
-+38
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+86
-+86
-+86
-+46
-+46
-+46
-+14
-+14
-+14
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+18
-+18
-+18
-+46
-+46
-+46
-+86
-+86
-+86
-+18
-+18
-+18
-+2
-+2
-+6
-+34
-+34
-+34
-+10
-+10
-+10
-+6
-+6
-+6
-+210
-+210
-+210
-+154
-+153
-+152
-+28
-+27
-+25
-+26
-+25
-+23
-+53
-+52
-+50
-+198
-+198
-+197
-+253
-+253
-+253
-+253
-+253
-+253
-+226
-+226
-+226
-+119
-+119
-+118
-+27
-+26
-+24
-+94
-+93
-+92
-+181
-+181
-+180
-+157
-+157
-+157
-+60
-+59
-+56
-+61
-+60
-+58
-+173
-+173
-+172
-+246
-+246
-+246
-+253
-+253
-+253
-+161
-+161
-+161
-+27
-+26
-+24
-+26
-+25
-+23
-+90
-+90
-+90
-+230
-+230
-+229
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+221
-+221
-+221
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+6
-+6
-+6
-+30
-+30
-+30
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+82
-+82
-+82
-+54
-+54
-+54
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+26
-+26
-+26
-+66
-+66
-+66
-+62
-+62
-+62
-+2
-+2
-+6
-+2
-+2
-+6
-+38
-+38
-+38
-+10
-+10
-+10
-+26
-+26
-+26
-+238
-+238
-+238
-+226
-+226
-+226
-+79
-+79
-+77
-+26
-+25
-+23
-+50
-+50
-+50
-+181
-+181
-+180
-+249
-+249
-+249
-+253
-+253
-+253
-+247
-+247
-+247
-+198
-+198
-+197
-+144
-+143
-+142
-+106
-+106
-+106
-+100
-+99
-+98
-+95
-+95
-+93
-+127
-+127
-+127
-+192
-+192
-+192
-+251
-+251
-+251
-+253
-+253
-+253
-+216
-+215
-+215
-+79
-+79
-+77
-+26
-+25
-+23
-+26
-+25
-+23
-+29
-+28
-+27
-+181
-+181
-+180
-+252
-+252
-+252
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+231
-+231
-+231
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+10
-+10
-+10
-+30
-+30
-+30
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+66
-+66
-+66
-+58
-+58
-+58
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+10
-+10
-+10
-+38
-+38
-+38
-+78
-+78
-+78
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+46
-+46
-+46
-+14
-+14
-+14
-+42
-+42
-+42
-+246
-+246
-+246
-+250
-+250
-+250
-+161
-+161
-+161
-+36
-+35
-+33
-+26
-+25
-+23
-+53
-+52
-+50
-+130
-+130
-+129
-+208
-+208
-+208
-+249
-+249
-+249
-+253
-+253
-+253
-+253
-+253
-+253
-+230
-+230
-+229
-+210
-+210
-+210
-+214
-+214
-+214
-+242
-+242
-+242
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+196
-+196
-+195
-+46
-+46
-+46
-+26
-+25
-+23
-+26
-+25
-+23
-+26
-+25
-+23
-+94
-+93
-+92
-+231
-+231
-+230
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+234
-+234
-+234
-+10
-+10
-+10
-+2
-+2
-+6
-+2
-+2
-+6
-+22
-+22
-+22
-+14
-+14
-+14
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+66
-+66
-+66
-+62
-+62
-+62
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+18
-+18
-+18
-+50
-+50
-+50
-+74
-+74
-+74
-+2
-+2
-+6
-+2
-+2
-+6
-+14
-+14
-+14
-+70
-+70
-+70
-+34
-+34
-+34
-+62
-+62
-+62
-+250
-+250
-+250
-+253
-+253
-+253
-+224
-+223
-+223
-+84
-+83
-+82
-+26
-+25
-+23
-+26
-+25
-+23
-+34
-+33
-+31
-+74
-+73
-+72
-+144
-+144
-+144
-+203
-+203
-+202
-+240
-+240
-+239
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+231
-+231
-+230
-+106
-+105
-+104
-+26
-+25
-+23
-+26
-+25
-+23
-+26
-+25
-+23
-+38
-+37
-+36
-+173
-+173
-+172
-+250
-+250
-+250
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+234
-+234
-+234
-+14
-+14
-+14
-+2
-+2
-+6
-+2
-+2
-+6
-+30
-+30
-+30
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+66
-+66
-+66
-+62
-+62
-+62
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+18
-+18
-+18
-+54
-+54
-+54
-+62
-+62
-+62
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+30
-+30
-+30
-+46
-+46
-+46
-+70
-+70
-+70
-+250
-+250
-+250
-+253
-+253
-+253
-+249
-+249
-+249
-+159
-+158
-+157
-+32
-+31
-+28
-+26
-+25
-+23
-+26
-+25
-+23
-+26
-+25
-+23
-+39
-+38
-+37
-+69
-+69
-+67
-+106
-+105
-+104
-+137
-+137
-+137
-+171
-+171
-+170
-+228
-+228
-+228
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+176
-+176
-+175
-+35
-+34
-+32
-+26
-+25
-+23
-+26
-+25
-+23
-+26
-+25
-+23
-+99
-+98
-+97
-+230
-+230
-+229
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+226
-+226
-+226
-+10
-+10
-+10
-+2
-+2
-+6
-+6
-+6
-+6
-+30
-+30
-+30
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+66
-+66
-+66
-+58
-+58
-+58
-+22
-+22
-+22
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+22
-+22
-+22
-+58
-+58
-+58
-+62
-+62
-+62
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+30
-+30
-+30
-+78
-+78
-+78
-+250
-+250
-+250
-+253
-+253
-+253
-+253
-+253
-+253
-+228
-+228
-+228
-+74
-+74
-+74
-+26
-+25
-+23
-+25
-+24
-+22
-+26
-+25
-+23
-+26
-+25
-+23
-+27
-+26
-+24
-+29
-+28
-+27
-+35
-+34
-+32
-+44
-+43
-+41
-+135
-+135
-+134
-+251
-+251
-+251
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+228
-+228
-+228
-+95
-+95
-+93
-+26
-+25
-+23
-+26
-+25
-+23
-+26
-+25
-+23
-+44
-+43
-+41
-+176
-+176
-+175
-+252
-+252
-+252
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+206
-+206
-+206
-+2
-+2
-+6
-+22
-+22
-+22
-+34
-+34
-+34
-+18
-+14
-+6
-+22
-+22
-+22
-+26
-+26
-+26
-+18
-+18
-+18
-+6
-+6
-+6
-+2
-+2
-+6
-+2
-+2
-+6
-+82
-+82
-+82
-+54
-+54
-+54
-+18
-+18
-+18
-+6
-+6
-+6
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+0
-+6
-+6
-+6
-+26
-+26
-+26
-+62
-+62
-+62
-+106
-+106
-+106
-+80
-+54
-+7
-+185
-+133
-+11
-+210
-+164
-+10
-+121
-+92
-+8
-+6
-+6
-+6
-+62
-+62
-+62
-+238
-+238
-+238
-+253
-+253
-+253
-+253
-+253
-+253
-+250
-+250
-+250
-+173
-+173
-+172
-+26
-+25
-+23
-+26
-+25
-+23
-+25
-+24
-+22
-+25
-+24
-+22
-+25
-+24
-+22
-+26
-+25
-+23
-+26
-+25
-+23
-+26
-+25
-+23
-+61
-+60
-+58
-+203
-+203
-+202
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+253
-+251
-+251
-+251
-+169
-+169
-+168
-+49
-+48
-+47
-+26
-+25
-+23
-+26
-+25
-+23
-+26
-+25
-+23
-+95
-+95
-+93
-+231
-+231
-+230
-+253
-+253
-+253
-+253
-+253
-+253
-+253
...
[truncated message content] |
|
From: <ar...@us...> - 2008-07-25 15:56:48
|
Revision: 857
http://armadeus.svn.sourceforge.net/armadeus/?rev=857&view=rev
Author: artemys
Date: 2008-07-25 15:56:57 +0000 (Fri, 25 Jul 2008)
Log Message:
-----------
[LINUX] Rename I2C patch
Added Paths:
-----------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/018-linux-2.6.23.1-i2c-imx.diff
Removed Paths:
-------------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/014-linux-2.6.23.1-i2c-imx.diff
Deleted: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/014-linux-2.6.23.1-i2c-imx.diff
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/014-linux-2.6.23.1-i2c-imx.diff 2008-07-25 15:39:19 UTC (rev 856)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/014-linux-2.6.23.1-i2c-imx.diff 2008-07-25 15:56:57 UTC (rev 857)
@@ -1,847 +0,0 @@
---- ref/linux-2.6.23/drivers/i2c/busses/i2c-imx.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.23/drivers/i2c/busses/i2c-imx.c 2007-01-14 14:08:13.000000000 +0100
-@@ -0,0 +1,641 @@
-+/*
-+ * Copyright (C) 2002 Motorola GSG-China
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version 2
-+ * of the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ *
-+ * File Name: i2c-imx.c
-+ *
-+ * Author: Torsten Koschorrek, synertronixx GmbH
-+ *
-+ * Desc.: Implementation of I2C Adapter/Algorithm Driver
-+ * Driver for I2C Bus integrated in i.MXL, i.MX1
-+ *
-+ * compiler options: - I2C_IMX_DEBUG:
-+ * Enables debug output. If not set, no debug
-+ * is compiled into the driver.
-+ * - I2C_IMX_SLAVESUPPORT:
-+ * This option enables support for slaves.
-+ * Userspace programs are set into sleep state, if
-+ * no new data is available from the slave. The
-+ * timing parameters are defined in additional
-+ * modules. Now supported are ads1110 and m41t00.
-+ *
-+ * module parameter: - dbg:
-+ * Enables debug output. Default is off.
-+ * - clkdiv:
-+ * Sets the clk clock rate divider. The default
-+ * value is #0x0F (240) (400kHz i2c / 96MHz HCLK).
-+ *
-+ * Derived from Motorola GSG China I2C example driver
-+ *
-+ * Copyright (C) 2002 Motorola GSG-China
-+ * Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de>
-+ * Portions:
-+ * Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de>
-+ *
-+ * History: 2002/2/07 use msgs[]
-+ * Motorola GSG-China
-+ * 2004/3/03 port to linux kernel v2.6.x for i.MX
-+ * adding ioctl (change bus freq)
-+ * adding cpu- and bus-usage optimization (..slp)
-+ * T. Koschorrek <koschorrek at synertronixx.de>
-+ * 2005/2/28 changes in timings
-+ * M. Blaschke <blaschke at synertronixx.de>
-+ * 2005/6/01 added module parameters, cleaning up, cpu- and bus-usage
-+ * modularized (..slave)
-+ * T. Koschorrek <koschorrek at synertronixx.de>
-+ * 2007/1/14 fix i2c_imx_read/write to return number of messages
-+ * processed.
-+ * Change form for compatibility with kernel > 2.6.18.
-+ * Change default CLKDIV to 0x0F (400kHz i2c / 96MHz HCLK).
-+ * Jorasse <jo...@us...>
-+ */
-+
-+#include "i2c-imx.h"
-+
-+/*-----------------------------------------------------------------------------
-+ * functions (IMX related code)
-+ *---------------------------------------------------------------------------*/
-+static int i2c_imx_bus_grab(void)
-+{
-+ long int i = 0;
-+ int timeout = I2C_IMX_TIME_GRAB;
-+
-+ /* wait for bus grab */
-+ while((!((i2c_imx_reg->i2sr & (u32)0x30))) && (i < timeout)) {
-+ i++;
-+ };
-+
-+ if (i == timeout)
-+ return -I2C_IMX_ERR_GRAB;
-+
-+ return 0;
-+}
-+
-+static int i2c_imx_bus_busy(void)
-+{
-+ int i = 0;
-+ int timeout = I2C_IMX_TIME_BUSY;
-+
-+ /* wait for bus not busy */
-+ while((i2c_imx_reg->i2sr & (u32)0x20) && (i < timeout))
-+ i++;
-+
-+ if (i == timeout)
-+ return -I2C_IMX_ERR_BUSY;
-+
-+ return 0;
-+}
-+
-+static int i2c_imx_received_acknowledge(void)
-+{
-+ if (i2c_imx_i2sr & 0x01)
-+ return -I2C_IMX_ERR_RXACK;
-+
-+ return 0;
-+}
-+
-+static int i2c_imx_transfer_complete(void)
-+{
-+ int i = 0;
-+ unsigned long flags;
-+ int timeout = I2C_IMX_TIME_TXCOMPLETE;
-+
-+ i2c_imx_i2sr = 0x00;
-+
-+ /* wait for transfer complete interrupt */
-+ while ((!(i2c_imx_irq_ok)) && (i < timeout)) {
-+ spin_lock_irqsave(&i2c_imx_irqlock, flags);
-+ i++;
-+ spin_unlock_irqrestore(&i2c_imx_irqlock, flags);
-+ }
-+
-+ i2c_imx_irq_ok = 0;
-+
-+ if (i == timeout)
-+ return -I2C_IMX_ERR_TXCOMPLETE;
-+
-+ return 0;
-+}
-+
-+static int i2c_imx_bus_release(void)
-+{
-+ int i = 0;
-+ int dummy;
-+ int timeout = I2C_IMX_TIME_RELEASE;
-+
-+ /* if bus busy reset the module process suggested in reference manual
-+ (tahiti) */
-+ if (i2c_imx_bus_busy() && (i < timeout)) {
-+ i2c_imx_reg->i2cr = (u32)0x00;
-+ i2c_imx_reg->i2cr |= (u32)0x0a;
-+ dummy = (u8)i2c_imx_reg->i2dr;
-+ i2c_imx_reg->i2sr = (u32)0x00;
-+ i2c_imx_reg->i2cr = (u32)0x00;
-+ i2c_imx_reg->i2cr &= ~((u32)0x80);
-+ i++;
-+ }
-+
-+ return 0;
-+}
-+
-+static int i2c_imx_start(void)
-+{
-+ int i = 0;
-+ int timeout = I2C_IMX_MAX_GRAB;
-+
-+ /* Set Master Mode */
-+ i2c_imx_reg->i2cr |= 0x20;
-+
-+ /* wait while bus grab */
-+ while((i2c_imx_bus_grab()) && (i < timeout)) {
-+ i2c_imx_reg->i2cr &= ~((u32)0x20); /* bus stop */
-+ i2c_imx_bus_release();
-+ if (i2c_imx_bus_busy() < 0)
-+ return -I2C_IMX_ERR_BUSY;
-+ i2c_imx_reg->i2cr |= (u32)0x80; /* [I2CR:IEN] (I2C Enable) */
-+ i2c_imx_reg->i2cr |= (u32)0x08; /* [I2CR:TXAK] dable txack */
-+ i2c_imx_reg->i2cr |= (u32)0x20; /* Set Master Mode */
-+ i++;
-+ }
-+
-+ if (i == timeout)
-+ return -I2C_IMX_ERR_GRAB;
-+
-+ return 0;
-+}
-+
-+static int i2c_imx_write(int i, int *count, struct i2c_msg *msgs)
-+{
-+ int j;
-+
-+ /* select slave */
-+ i2c_imx_reg->i2dr = msgs->addr << 1;
-+ if (i2c_imx_transfer_complete() < 0)
-+ return -I2C_IMX_ERR_TXCOMPLETE;
-+ if (i2c_imx_received_acknowledge() < 0)
-+ return -I2C_IMX_ERR_RXACK;
-+
-+ /* write data */
-+ for ( j = 0; j < msgs->len; j ++ )
-+ {
-+ i2c_imx_reg->i2dr = msgs->buf[j];
-+ if (i2c_imx_transfer_complete() < 0)
-+ return -I2C_IMX_ERR_TXCOMPLETE;
-+ }
-+
-+ (*count)++;
-+
-+ return 0;
-+}
-+
-+static int i2c_imx_read(int i, int *count, struct i2c_msg *msgs)
-+{
-+ int j;
-+ int dummy;
-+
-+ /* select slave */
-+ i2c_imx_reg->i2dr = ((u32)msgs->addr << 1) | (u32)0x01;
-+ if (i2c_imx_transfer_complete() < 0)
-+ return -I2C_IMX_ERR_TXCOMPLETE;
-+ if (i2c_imx_received_acknowledge() < 0)
-+ return -I2C_IMX_ERR_RXACK;
-+
-+ /* setup bus to read data */
-+ i2c_imx_reg->i2cr &= ~(u32)0x10;
-+ if (msgs->len-1)
-+ i2c_imx_reg->i2cr &= ~(u32)0x08;
-+ dummy = (u8)i2c_imx_reg->i2dr; /* trigger rec. of next byte */
-+ if (i2c_imx_transfer_complete() < 0)
-+ return -I2C_IMX_ERR_TXCOMPLETE;
-+
-+ /* read data */
-+ for ( j = 0; j < msgs->len; j ++ )
-+ {
-+ if (j == (msgs->len - 1))
-+ i2c_imx_reg->i2cr |= 0x08;
-+
-+ msgs->buf[j] = (u8)i2c_imx_reg->i2dr;
-+ if (i2c_imx_transfer_complete() < 0)
-+ return -I2C_IMX_ERR_TXCOMPLETE;
-+ }
-+
-+ (*count)++;
-+
-+ return 0;
-+}
-+
-+#ifdef I2C_IMX_SLAVESUPPORT
-+void i2c_imx_add_slave(struct i2c_slave slave) {
-+ i2c_imx_slave[slave.address-1] = slave;
-+ slave.last_ct = jiffies;
-+
-+ I2C_DBG("I2C slave added: Chip-Desc.: %s (slave address: 0x%x)\n",
-+ slave.name, slave.address);
-+
-+ return;
-+}
-+
-+void i2c_imx_del_slave(struct i2c_slave slave) {
-+ I2C_DBG("Remove I2C slave: Chip-Desc.: %s (slave address: 0x%x)\n",
-+ slave.name, slave.address);
-+
-+ return;
-+}
-+#endif
-+
-+/*-----------------------------------------------------------------------------
-+ * static irqreturn_t i2c_imx_isr (s16 irq, void * dev_id, struct pt_regs *
-+ * reg)
-+ * This function deals with the interrupt for the I2C module.
-+ *
-+ * Parameters: irq the interrupt number
-+ * dev_id device id
-+ * reg processor register
-+ * Return: IRQ_HANDLED the own irq was handled
-+ *---------------------------------------------------------------------------*/
-+static irqreturn_t i2c_imx_isr (s16 irq, void *dev_id, struct pt_regs * reg)
-+{
-+ /* safe status register */
-+ i2c_imx_i2sr = i2c_imx_reg->i2sr;
-+
-+ /* if data transfer is complete set ok */
-+ if (i2c_imx_i2sr & (u32)0x80) /* [I2SR:ICF] TX complete */
-+ i2c_imx_irq_ok = 1;
-+
-+ /* clear irq */
-+ i2c_imx_reg->i2sr &= ~(u32)0x02; /* clear [I2SR:IIF] Interrupt */
-+
-+ return IRQ_HANDLED;
-+}
-+
-+/*-----------------------------------------------------------------------------
-+ * int i2c_imx_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[ ],
-+ * SINT16 num)
-+ * This function is responsible for the transfer of the data through the
-+ * I2C bus
-+ *
-+ * Parameter: i2c_adap associated with the related hardware
-+ * msgs[ ] the body of the message to be send out
-+ * num number of message
-+ * Return: Success Number of message has been transferred
-+ * Failure -err (error code)
-+ *---------------------------------------------------------------------------*/
-+static int i2c_imx_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[],
-+ int num)
-+{
-+ int i;
-+ int count = 0;
-+ int err = 0;
-+
-+ for(i = 0; i < num; i++)
-+ I2C_DBG("i2c_adap.%d %s: msg: %d, len: %d, dir: %s, address: "
-+ "0x%x\n", i2c_imx_adapter.nr, __FUNCTION__, i,
-+ msgs[i].len, (msgs[i].flags & I2C_M_RD)?"rd":"wr",
-+ msgs[i].addr);
-+
-+#ifdef I2C_IMX_SLAVESUPPORT
-+ struct i2c_slave *slave = &i2c_imx_slave[msgs[0].addr-1];
-+
-+ if(slave->address == msgs[0].addr) {
-+ unsigned long last_ct = slave->last_ct;
-+ int slp_time = slave->slp_time;
-+ int slp = slp_time * HZ / 1000 - (jiffies - last_ct);
-+ DECLARE_WAIT_QUEUE_HEAD(wait);
-+
-+ // scheduler: sleep while slave not ready
-+ if ((slp > 1) && (msgs[0].flags & I2C_M_RD)) {
-+ up(&i2c_adap->bus_lock);
-+ sleep_on_timeout(&wait, slp);
-+ down(&i2c_adap->bus_lock);
-+ }
-+ }
-+#endif
-+
-+ /* enable the i2c-bus, disable the I2C transmit ACK */
-+ if ((err = i2c_imx_bus_busy()) < 0)
-+ goto EXIT_FKT;
-+ i2c_imx_reg->i2cr |= (u32)0x80;
-+ i2c_imx_reg->i2cr |= (u32)0x08;
-+
-+ for ( i = 0; i < num; i ++)
-+ {
-+ /* repeat start else start the bus-transfer */
-+ if (i)
-+ i2c_imx_reg->i2cr |= (u32)0x04;
-+ else
-+ if ((err = i2c_imx_start()) < 0)
-+ goto EXIT_FKT;
-+
-+ /* enable interrupt, enable master transmit */
-+ i2c_imx_reg->i2cr |= (u32)0x40;
-+ i2c_imx_reg->i2cr |= (u32)0x10;
-+
-+ /* write/read data */
-+ if (!(msgs[i].flags & I2C_M_RD)) {
-+ if ((err = i2c_imx_write(i, &count, &msgs[i])) < 0)
-+ goto EXIT_FKT;
-+ } else {
-+ if ((err = i2c_imx_read(i, &count, &msgs[i])) < 0)
-+ goto EXIT_FKT;
-+ }
-+ }
-+
-+EXIT_FKT:
-+ /* disable i2c bus */
-+ i2c_imx_reg->i2cr &= ~((u32)0x20); /* bus stop */
-+ i2c_imx_bus_release();
-+ i2c_imx_reg->i2cr &= ~((u32)0x80); /* disable I2C */
-+
-+#ifdef I2C_IMX_SLAVESUPPORT
-+ /* define ms to sleep after read from chip */
-+ if (!(msgs[0].flags & I2C_M_RD) && (slave->address == msgs[0].addr))
-+ slave->slp_time = slave->get_slp_time(&msgs[0]);
-+
-+ slave->last_ct = jiffies;
-+#endif
-+ if(err == 0)
-+ return count;
-+
-+ switch (err) {
-+ case -I2C_IMX_ERR_RXACK:
-+ i2c_imx_errcnt_rxack++;
-+ break;
-+ case -I2C_IMX_ERR_TXCOMPLETE:
-+ i2c_imx_errcnt_txcomplete++;
-+ break;
-+ case -I2C_IMX_ERR_BUSY:
-+ i2c_imx_errcnt_busy++;
-+ break;
-+ case -I2C_IMX_ERR_GRAB:
-+ i2c_imx_errcnt_grab++;
-+ break;
-+ }
-+
-+ I2C_ERR("I2C transfer error\n");
-+ I2C_ERRCNT
-+
-+ return err;
-+}
-+
-+/*-----------------------------------------------------------------------------
-+ * int i2c_smbus_imx_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[ ],
-+ * SINT16 num)
-+ * This function is responsible for the transfer of the data through the
-+ * I2C-bus
-+ *
-+ * Parameter : i2c_adap the structure associated with the related hardware
-+ * msgs[ ] the body of the message to be send out
-+ * num number of message
-+ * Return : Success Number of message has been transferred
-+ * Failure -1
-+ *---------------------------------------------------------------------------*/
-+static int i2c_imx_smbus(struct i2c_adapter * adapter, u16 addr,
-+ unsigned short flags, char read_write, u8 command,
-+ int size, union i2c_smbus_data * data)
-+{
-+ char msgbuf0[34];
-+ char msgbuf1[34];
-+ int num = read_write == I2C_SMBUS_READ?2:1;
-+ struct i2c_msg msg[2] = {
-+ { addr, flags, 1, msgbuf0 },
-+ { addr, flags | I2C_M_RD, 10, msgbuf1 }
-+ };
-+ int i;
-+ msgbuf0[0] = command;
-+
-+ /* select the smbus-command and create the message */
-+ switch(size) {
-+ case I2C_SMBUS_QUICK:
-+ msg[0].len = 0;
-+ msg[0].flags=flags|(read_write==I2C_SMBUS_READ)?I2C_M_RD:0;
-+ num = 1;
-+ break;
-+ case I2C_SMBUS_BYTE:
-+ if (read_write == I2C_SMBUS_READ) {
-+ msg[0].flags = I2C_M_RD | flags;
-+ num = 1;
-+ }
-+ break;
-+ case I2C_SMBUS_BYTE_DATA:
-+ if (read_write == I2C_SMBUS_READ)
-+ msg[1].len = 1;
-+ else {
-+ msg[0].len = 2;
-+ msgbuf0[1] = data->byte;
-+ }
-+ break;
-+ case I2C_SMBUS_WORD_DATA:
-+ if (read_write == I2C_SMBUS_READ)
-+ msg[1].len = 2;
-+ else {
-+ msg[0].len=3;
-+ msgbuf0[1] = data->word & 0xff;
-+ msgbuf0[2] = (data->word >> 8) & 0xff;
-+ }
-+ break;
-+ case I2C_SMBUS_PROC_CALL:
-+ num = 2;
-+ msg[0].len = 3;
-+ msg[1].len = 2;
-+ msgbuf0[1] = data->word & 0xff;
-+ msgbuf0[2] = (data->word >> 8) & 0xff;
-+ break;
-+ case I2C_SMBUS_BLOCK_DATA:
-+ if (read_write == I2C_SMBUS_READ) {
-+ return -I2C_IMX_ERR_SMBUS_XFER;
-+ } else {
-+ msg[0].len = data->block[0] + 2;
-+ if (msg[0].len > 34) {
-+ return -I2C_IMX_ERR_SMBUS_XFER;
-+ }
-+ for (i = 1; i <= msg[0].len; i++)
-+ msgbuf0[i] = data->block[i-1];
-+ }
-+ break;
-+ default:
-+ return -I2C_IMX_ERR_SMBUS_XFER;
-+ }
-+
-+ /* call the bus access routine */
-+ if (i2c_imx_xfer(adapter, msg, num) < 0)
-+ return -I2C_IMX_ERR_SMBUS_XFER;
-+
-+ /* copy the readed bytes to the data-field */
-+ if (read_write == I2C_SMBUS_READ)
-+ switch(size) {
-+ case I2C_SMBUS_BYTE:
-+ data->byte = msgbuf0[0];
-+ break;
-+ case I2C_SMBUS_BYTE_DATA:
-+ data->byte = msgbuf1[0];
-+ break;
-+ case I2C_SMBUS_WORD_DATA:
-+ case I2C_SMBUS_PROC_CALL:
-+ data->word = msgbuf1[0] | (msgbuf1[1] << 8);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+/*-----------------------------------------------------------------------------
-+ * int i2c_imx_ioctl(struct i2c_adapter * adapter, unsigned int cmd,
-+ * unsigned long arg)
-+ * This function control the I2C module itself
-+ *
-+ * Parameters: Adapter the adapter associated to the I2C module
-+ * Cmd IO control command
-+ * Arg argument associated with the command
-+ * Return : Success 0
-+ *---------------------------------------------------------------------------*/
-+static int i2c_imx_ioctl(struct i2c_adapter * adapter, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ switch( cmd ) {
-+ case I2C_IMX_IO_SET_CLKDIV:
-+ I2C_DBG("i2c_adap.%d %s: Set I2C Clock Rate Divider to #0x%02x"
-+ "\n", i2c_imx_adapter.nr, __FUNCTION__,
-+ (u32)(arg & 0x003f));
-+ i2c_imx_reg->ifdr = (u32)(arg & 0x003f);
-+ break;
-+ case I2C_IMX_IO_GET_CLKDIV:
-+ I2C_DBG("i2c_adap.%d %s: Get I2C Clock Rate Divider\n",
-+ i2c_imx_adapter.nr, __FUNCTION__);
-+ arg = i2c_imx_reg->ifdr & 0x003f;
-+ I2C_DBG("i2c_adap.%d %s: I2C Clock Rate Divider is #0x%02x"
-+ "\n", i2c_imx_adapter.nr, __FUNCTION__,
-+ (unsigned int)arg);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+/*-----------------------------------------------------------------------------
-+ * u32 i2c_imx_func(struct i2c_adapter *i2c_adap)
-+ * This function returns the functionalities the adapter supports
-+ *
-+ * Parameter: i2c_adap associated with the related hardware
-+ * Return: u32 pattern of supported functionalities (i2c.h)
-+ *
-+ *---------------------------------------------------------------------------*/
-+static u32 i2c_imx_func(struct i2c_adapter *adap)
-+{
-+ return I2C_FUNC_I2C |
-+ I2C_FUNC_SMBUS_QUICK |
-+ I2C_FUNC_SMBUS_BYTE |
-+ I2C_FUNC_SMBUS_BYTE_DATA |
-+ I2C_FUNC_SMBUS_WORD_DATA |
-+ I2C_FUNC_SMBUS_PROC_CALL |
-+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA;
-+}
-+
-+/*-----------------------------------------------------------------------------
-+ * int __init i2c_imx_init(void)
-+ * initializes the I2C module in the DBIMX, and registers itself to the
-+ * Linux I2C system
-+ *
-+ * Parameters: None
-+ * Return: 0: indicates SUCCESS
-+ * -1: indicates FAILURE
-+ *---------------------------------------------------------------------------*/
-+static int __init i2c_imx_init(void)
-+{
-+ i2c_imx_dbg = dbg;
-+ i2c_imx_clkdiv = clkdiv;
-+
-+ /* Pin Configuration for I2C:
-+ * 2 Pins are available for the I2C-Module. These Pins are multiplexed
-+ * with other functions on the device and must be configured for SPI-
-+ * Operation.
-+ * The Data Direction Bits in the GPIO Data Direction Register Port A
-+ * must be set for Output.
-+ * The Function Bits in the GPIO In Use Register Port A must be set
-+ * for Multiplexed.
-+ * Data Direction (DDIR): Output
-+ * GPIO-Function (GIUS): SPI-Operation
-+ * GPR, PUEN: for Interrupt operations */
-+ imx_gpio_mode(PA15_PF_I2C_SDA);
-+ imx_gpio_mode(PA16_PF_I2C_SCL);
-+
-+ /* install the I2C_IMX ISR to the Linux Kernel */
-+ if (request_irq(I2C_INT, (void *)i2c_imx_isr, IRQF_DISABLED,
-+ "I2C_IMX", "i2c_bus") < 0)
-+ return -I2C_IMX_ERR_INIT;
-+
-+ /* add the I2C adapter/algorithm driver to the linux kernel */
-+ if (i2c_add_adapter(&i2c_imx_adapter))
-+ return -I2C_IMX_ERR_INIT;
-+
-+ I2C_DBG("%s, ver.: %s\n", I2C_IMX_DRIVER_DESC, I2C_IMX_DRIVER_VERSION);
-+
-+ I2C_DBG("New I2C adapter %d found\n", i2c_imx_adapter.nr);
-+
-+ /* Set clock Freq. */
-+ i2c_imx_reg->ifdr = (u32)i2c_imx_clkdiv;
-+ I2C_DBG("i2c_adap.%d I2C Clock Rate Divider set to #0x%x\n",
-+ i2c_imx_adapter.nr, i2c_imx_clkdiv);
-+
-+#ifdef I2C_IMX_SLAVESUPPORT
-+ /* define ms to sleep after read from chip */
-+ I2C_DBG("i2c_adap.%d I2C slave support added\n",
-+ i2c_imx_adapter.nr);
-+#endif
-+
-+ return 0;
-+}
-+
-+/*-----------------------------------------------------------------------------
-+ * void __exit i2c_imx_cleanup(void)
-+ * This routine is called when the driver is unloaded
-+ *
-+ * Parameters: None
-+ * Return: None
-+ *---------------------------------------------------------------------------*/
-+static void __exit i2c_imx_cleanup(void)
-+{
-+ I2C_ERRCNT
-+
-+ I2C_DBG("I2C adapter removed\n");
-+
-+ /* unset IEN[I2CR:7] (I2C Disable) */
-+ i2c_imx_reg->i2cr = (u32)0x00;
-+
-+ /* Free IRQ */
-+ free_irq (I2C_INT, "i2c_bus");
-+
-+ /* Delete Adapter from Kernel */
-+ i2c_del_adapter(&i2c_imx_adapter);
-+}
-+
-+module_init(i2c_imx_init);
-+module_exit(i2c_imx_cleanup);
-+
-+MODULE_AUTHOR(I2C_IMX_DRIVER_AUTHOR);
-+MODULE_DESCRIPTION(I2C_IMX_DRIVER_DESC);
-+MODULE_LICENSE("GPL");
-+
-+module_param(dbg, bool, 0);
-+MODULE_PARM_DESC(dbg, "Debug enabled or not");
-+
-+module_param(clkdiv, int, I2C_IMX_DEFAULT_CLKDIV);
-+MODULE_PARM_DESC(clkdiv, "I2C Clock Rate Divider");
-+
-+#ifdef I2C_IMX_SLAVESUPPORT
-+EXPORT_SYMBOL(i2c_imx_add_slave);
-+EXPORT_SYMBOL(i2c_imx_del_slave);
-+#endif
---- ref/linux-2.6.23/drivers/i2c/busses/i2c-imx.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.23/drivers/i2c/busses/i2c-imx.h 2007-01-14 14:08:26.000000000 +0100
-@@ -0,0 +1,176 @@
-+/*
-+ * Copyright (C) 2002 Motorola GSG-China
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version 2
-+ * of the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-+ * USA.
-+ *
-+ * File Name: i2c-imx.h
-+ *
-+ * Author: Torsten Koschorrek, synertronixx GmbH
-+ *
-+ * Desc.: Implementation of I2C Adapter/Algorithm Driver
-+ *
-+ * Derived from Motorola GSG China I2C example driver
-+ *
-+ * Copyright (C) 2002 Motorola GSG-China
-+ * Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de>
-+ * Portions:
-+ * Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de>
-+ *
-+ * History: 2002/2/07 use msgs[]
-+ * Motorola GSG-China
-+ * 2004/3/03 port to linux kernel v2.6.x for i.MX
-+ * adding ioctl (change bus freq)
-+ * adding cpu- and bus-usage optimization (..slp)
-+ * T. Koschorrek <koschorrek at synertronixx.de>
-+ * 2005/2/28 changes in timings
-+ * M. Blaschke <blaschke at synertronixx.de>
-+ * 2005/6/01 added module parameters, cleaning up, cpu- and bus-usage
-+ * modularized (..slave)
-+ * T. Koschorrek <koschorrek at synertronixx.de>
-+ * 2007/1/14 fix i2c_imx_read/write to return number of messages
-+ * processed.
-+ * Change form for compatibility with kernel > 2.6.18.
-+ * Change default CLKDIV to 0x0F (400kHz i2c / 96MHz HCLK).
-+ * Jorasse <jo...@us...>
-+ */
-+
-+#include <linux/i2c.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <linux/spinlock.h>
-+
-+#include <asm/arch/irqs.h>
-+#include <asm/arch/hardware.h>
-+
-+#define I2C_IMX_DRIVER_VERSION "14 January 2007"
-+#define I2C_IMX_DRIVER_AUTHOR "T. Koschorrek, synertronixx GmbH"
-+#define I2C_IMX_DRIVER_DESC "I2C Adapter/Algorithm driver"
-+
-+#define I2C_IMX_DEFAULT_DEBUG 0
-+#define I2C_IMX_DEFAULT_CLKDIV 16 // 0x0f
-+
-+#define I2C_IMX_TIME_GRAB 2000
-+#define I2C_IMX_TIME_BUSY 2000
-+#define I2C_IMX_TIME_RELEASE 2000
-+#define I2C_IMX_TIME_TXCOMPLETE 2000
-+#define I2C_IMX_MAX_GRAB 3
-+
-+#define I2C_IMX_IO_SET_CLKDIV 0xaa
-+#define I2C_IMX_IO_GET_CLKDIV 0xab
-+
-+#define I2C_IMX_ERR_INIT 0x01
-+#define I2C_IMX_ERR_SMBUS_XFER 0x02
-+#define I2C_IMX_ERR_RXACK 0x03
-+#define I2C_IMX_ERR_TXCOMPLETE 0x04
-+#define I2C_IMX_ERR_BUSY 0x05
-+#define I2C_IMX_ERR_GRAB 0x06
-+
-+
-+
-+#ifdef I2C_IMX_SLAVESUPPORT
-+#include "i2c-imx-slave.h"
-+#endif
-+
-+
-+
-+/* function declarations */
-+static int i2c_imx_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[ ],
-+ int num);
-+static int i2c_imx_smbus(struct i2c_adapter * adapter, u16 addr,
-+ unsigned short flags, char read_write, u8 command,
-+ int size, union i2c_smbus_data * data);
-+static int i2c_imx_ioctl(struct i2c_adapter * adapter, unsigned int cmd,
-+ unsigned long arg);
-+static u32 i2c_imx_func(struct i2c_adapter *adap);
-+
-+/* structs */
-+static struct i2c_algorithm i2c_imx_algorithm = {
-+ .master_xfer = i2c_imx_xfer,
-+ .smbus_xfer = i2c_imx_smbus,
-+ .algo_control = i2c_imx_ioctl,
-+ .functionality = i2c_imx_func
-+};
-+
-+static struct i2c_adapter i2c_imx_adapter = {
-+ .owner = THIS_MODULE,
-+ .name = "IMX I2C adapter",
-+ .class = I2C_CLASS_HWMON,
-+ .algo = &i2c_imx_algorithm
-+};
-+
-+struct i2c_regs {
-+ /* address reg */ volatile u32 iadr;
-+ /* freq div. reg */ volatile u32 ifdr;
-+ /* control reg */ volatile u32 i2cr;
-+ /* status reg */ volatile u32 i2sr;
-+ /* data io reg */ volatile u32 i2dr;
-+};
-+
-+
-+
-+
-+/* global variables */
-+static struct i2c_regs *i2c_imx_reg = (struct i2c_regs *)IMX_I2C_BASE;
-+static spinlock_t i2c_imx_irqlock = SPIN_LOCK_UNLOCKED;
-+static int i2c_imx_irq_ok;
-+static int i2c_imx_i2sr;
-+
-+#ifdef I2C_IMX_SLAVESUPPORT
-+static struct i2c_slave i2c_imx_slave[128];
-+#endif
-+
-+int i2c_imx_errcnt_rxack = 0;
-+int i2c_imx_errcnt_txcomplete = 0;
-+int i2c_imx_errcnt_busy = 0;
-+int i2c_imx_errcnt_grab = 0;
-+
-+int dbg = I2C_IMX_DEFAULT_DEBUG;
-+int i2c_imx_dbg = I2C_IMX_DEFAULT_DEBUG;
-+int clkdiv = I2C_IMX_DEFAULT_CLKDIV;
-+int i2c_imx_clkdiv = I2C_IMX_DEFAULT_CLKDIV;
-+
-+
-+
-+
-+/* debug messages */
-+#ifdef DEBUG
-+#define I2C_DBG(stuff ...) { \
-+ if (i2c_imx_dbg) { \
-+ printk(KERN_NOTICE stuff); \
-+ } \
-+ }
-+#define I2C_ERR(stuff ...) { \
-+ if (i2c_imx_dbg) { \
-+ printk(KERN_ERR "i2c_adap.%d ", i2c_imx_adapter.nr);\
-+ printk(stuff); \
-+ } \
-+ }
-+#else
-+#define I2C_DBG(stuff ...) while(0){}
-+#define I2C_ERR(stuff ...) while(0){}
-+#endif
-+
-+#ifdef DEBUG
-+#define I2C_ERRCNT { \
-+ I2C_ERR(" RX ACK : %d Error(s)\n", i2c_imx_errcnt_rxack); \
-+ I2C_ERR(" TX COMPLETE: %d Error(s)\n", i2c_imx_errcnt_txcomplete);\
-+ I2C_ERR(" BUS BUSY : %d Error(s)\n", i2c_imx_errcnt_busy); \
-+ I2C_ERR(" BUS GRAB : %d Error(s)\n", i2c_imx_errcnt_grab); \
-+}
-+#else
-+#define I2C_ERRCNT
-+#endif
---- ref/linux-2.6.23/drivers/i2c/busses/Kconfig 2006-10-14 05:34:03.000000000 +0200
-+++ linux-2.6.23/drivers/i2c/busses/Kconfig 2007-01-14 00:35:15.000000000 +0100
-@@ -521,6 +521,11 @@ config I2C_PCA_ISA
-
- This driver can also be built as a module. If so, the module
- will be called i2c-pca-isa.
-+config I2C_IMX
-+ tristate "i2c bus on i.MX"
-+ depends on I2C
-+ help
-+ i2c implenentation on i.MX motorola prozessors
-
- This device is almost undetectable and using this driver on a
- system which doesn't have this device will result in long
---- ref/linux-2.6.23/drivers/i2c/busses/Makefile 2006-10-14 05:34:03.000000000 +0200
-+++ linux-2.6.23/drivers/i2c/busses/Makefile 2007-01-14 00:35:15.000000000 +0100
-@@ -41,6 +41,7 @@ obj-$(CONFIG_I2C_STUB) += i2c-stub.o
- obj-$(CONFIG_I2C_VIA) += i2c-via.o
- obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
- obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o
-+obj-$(CONFIG_I2C_IMX) += i2c-imx.o
- obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
- obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
-
Copied: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/018-linux-2.6.23.1-i2c-imx.diff (from rev 833, trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/014-linux-2.6.23.1-i2c-imx.diff)
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/018-linux-2.6.23.1-i2c-imx.diff (rev 0)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.23.1/018-linux-2.6.23.1-i2c-imx.diff 2008-07-25 15:56:57 UTC (rev 857)
@@ -0,0 +1,847 @@
+--- ref/linux-2.6.23/drivers/i2c/busses/i2c-imx.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.23/drivers/i2c/busses/i2c-imx.c 2007-01-14 14:08:13.000000000 +0100
+@@ -0,0 +1,641 @@
++/*
++ * Copyright (C) 2002 Motorola GSG-China
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++ * USA.
++ *
++ * File Name: i2c-imx.c
++ *
++ * Author: Torsten Koschorrek, synertronixx GmbH
++ *
++ * Desc.: Implementation of I2C Adapter/Algorithm Driver
++ * Driver for I2C Bus integrated in i.MXL, i.MX1
++ *
++ * compiler options: - I2C_IMX_DEBUG:
++ * Enables debug output. If not set, no debug
++ * is compiled into the driver.
++ * - I2C_IMX_SLAVESUPPORT:
++ * This option enables support for slaves.
++ * Userspace programs are set into sleep state, if
++ * no new data is available from the slave. The
++ * timing parameters are defined in additional
++ * modules. Now supported are ads1110 and m41t00.
++ *
++ * module parameter: - dbg:
++ * Enables debug output. Default is off.
++ * - clkdiv:
++ * Sets the clk clock rate divider. The default
++ * value is #0x0F (240) (400kHz i2c / 96MHz HCLK).
++ *
++ * Derived from Motorola GSG China I2C example driver
++ *
++ * Copyright (C) 2002 Motorola GSG-China
++ * Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de>
++ * Portions:
++ * Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de>
++ *
++ * History: 2002/2/07 use msgs[]
++ * Motorola GSG-China
++ * 2004/3/03 port to linux kernel v2.6.x for i.MX
++ * adding ioctl (change bus freq)
++ * adding cpu- and bus-usage optimization (..slp)
++ * T. Koschorrek <koschorrek at synertronixx.de>
++ * 2005/2/28 changes in timings
++ * M. Blaschke <blaschke at synertronixx.de>
++ * 2005/6/01 added module parameters, cleaning up, cpu- and bus-usage
++ * modularized (..slave)
++ * T. Koschorrek <koschorrek at synertronixx.de>
++ * 2007/1/14 fix i2c_imx_read/write to return number of messages
++ * processed.
++ * Change form for compatibility with kernel > 2.6.18.
++ * Change default CLKDIV to 0x0F (400kHz i2c / 96MHz HCLK).
++ * Jorasse <jo...@us...>
++ */
++
++#include "i2c-imx.h"
++
++/*-----------------------------------------------------------------------------
++ * functions (IMX related code)
++ *---------------------------------------------------------------------------*/
++static int i2c_imx_bus_grab(void)
++{
++ long int i = 0;
++ int timeout = I2C_IMX_TIME_GRAB;
++
++ /* wait for bus grab */
++ while((!((i2c_imx_reg->i2sr & (u32)0x30))) && (i < timeout)) {
++ i++;
++ };
++
++ if (i == timeout)
++ return -I2C_IMX_ERR_GRAB;
++
++ return 0;
++}
++
++static int i2c_imx_bus_busy(void)
++{
++ int i = 0;
++ int timeout = I2C_IMX_TIME_BUSY;
++
++ /* wait for bus not busy */
++ while((i2c_imx_reg->i2sr & (u32)0x20) && (i < timeout))
++ i++;
++
++ if (i == timeout)
++ return -I2C_IMX_ERR_BUSY;
++
++ return 0;
++}
++
++static int i2c_imx_received_acknowledge(void)
++{
++ if (i2c_imx_i2sr & 0x01)
++ return -I2C_IMX_ERR_RXACK;
++
++ return 0;
++}
++
++static int i2c_imx_transfer_complete(void)
++{
++ int i = 0;
++ unsigned long flags;
++ int timeout = I2C_IMX_TIME_TXCOMPLETE;
++
++ i2c_imx_i2sr = 0x00;
++
++ /* wait for transfer complete interrupt */
++ while ((!(i2c_imx_irq_ok)) && (i < timeout)) {
++ spin_lock_irqsave(&i2c_imx_irqlock, flags);
++ i++;
++ spin_unlock_irqrestore(&i2c_imx_irqlock, flags);
++ }
++
++ i2c_imx_irq_ok = 0;
++
++ if (i == timeout)
++ return -I2C_IMX_ERR_TXCOMPLETE;
++
++ return 0;
++}
++
++static int i2c_imx_bus_release(void)
++{
++ int i = 0;
++ int dummy;
++ int timeout = I2C_IMX_TIME_RELEASE;
++
++ /* if bus busy reset the module process suggested in reference manual
++ (tahiti) */
++ if (i2c_imx_bus_busy() && (i < timeout)) {
++ i2c_imx_reg->i2cr = (u32)0x00;
++ i2c_imx_reg->i2cr |= (u32)0x0a;
++ dummy = (u8)i2c_imx_reg->i2dr;
++ i2c_imx_reg->i2sr = (u32)0x00;
++ i2c_imx_reg->i2cr = (u32)0x00;
++ i2c_imx_reg->i2cr &= ~((u32)0x80);
++ i++;
++ }
++
++ return 0;
++}
++
++static int i2c_imx_start(void)
++{
++ int i = 0;
++ int timeout = I2C_IMX_MAX_GRAB;
++
++ /* Set Master Mode */
++ i2c_imx_reg->i2cr |= 0x20;
++
++ /* wait while bus grab */
++ while((i2c_imx_bus_grab()) && (i < timeout)) {
++ i2c_imx_reg->i2cr &= ~((u32)0x20); /* bus stop */
++ i2c_imx_bus_release();
++ if (i2c_imx_bus_busy() < 0)
++ return -I2C_IMX_ERR_BUSY;
++ i2c_imx_reg->i2cr |= (u32)0x80; /* [I2CR:IEN] (I2C Enable) */
++ i2c_imx_reg->i2cr |= (u32)0x08; /* [I2CR:TXAK] dable txack */
++ i2c_imx_reg->i2cr |= (u32)0x20; /* Set Master Mode */
++ i++;
++ }
++
++ if (i == timeout)
++ return -I2C_IMX_ERR_GRAB;
++
++ return 0;
++}
++
++static int i2c_imx_write(int i, int *count, struct i2c_msg *msgs)
++{
++ int j;
++
++ /* select slave */
++ i2c_imx_reg->i2dr = msgs->addr << 1;
++ if (i2c_imx_transfer_complete() < 0)
++ return -I2C_IMX_ERR_TXCOMPLETE;
++ if (i2c_imx_received_acknowledge() < 0)
++ return -I2C_IMX_ERR_RXACK;
++
++ /* write data */
++ for ( j = 0; j < msgs->len; j ++ )
++ {
++ i2c_imx_reg->i2dr = msgs->buf[j];
++ if (i2c_imx_transfer_complete() < 0)
++ return -I2C_IMX_ERR_TXCOMPLETE;
++ }
++
++ (*count)++;
++
++ return 0;
++}
++
++static int i2c_imx_read(int i, int *count, struct i2c_msg *msgs)
++{
++ int j;
++ int dummy;
++
++ /* select slave */
++ i2c_imx_reg->i2dr = ((u32)msgs->addr << 1) | (u32)0x01;
++ if (i2c_imx_transfer_complete() < 0)
++ return -I2C_IMX_ERR_TXCOMPLETE;
++ if (i2c_imx_received_acknowledge() < 0)
++ return -I2C_IMX_ERR_RXACK;
++
++ /* setup bus to read data */
++ i2c_imx_reg->i2cr &= ~(u32)0x10;
++ if (msgs->len-1)
++ i2c_imx_reg->i2cr &= ~(u32)0x08;
++ dummy = (u8)i2c_imx_reg->i2dr; /* trigger rec. of next byte */
++ if (i2c_imx_transfer_complete() < 0)
++ return -I2C_IMX_ERR_TXCOMPLETE;
++
++ /* read data */
++ for ( j = 0; j < msgs->len; j ++ )
++ {
++ if (j == (msgs->len - 1))
++ i2c_imx_reg->i2cr |= 0x08;
++
++ msgs->buf[j] = (u8)i2c_imx_reg->i2dr;
++ if (i2c_imx_transfer_complete() < 0)
++ return -I2C_IMX_ERR_TXCOMPLETE;
++ }
++
++ (*count)++;
++
++ return 0;
++}
++
++#ifdef I2C_IMX_SLAVESUPPORT
++void i2c_imx_add_slave(struct i2c_slave slave) {
++ i2c_imx_slave[slave.address-1] = slave;
++ slave.last_ct = jiffies;
++
++ I2C_DBG("I2C slave added: Chip-Desc.: %s (slave address: 0x%x)\n",
++ slave.name, slave.address);
++
++ return;
++}
++
++void i2c_imx_del_slave(struct i2c_slave slave) {
++ I2C_DBG("Remove I2C slave: Chip-Desc.: %s (slave address: 0x%x)\n",
++ slave.name, slave.address);
++
++ return;
++}
++#endif
++
++/*-----------------------------------------------------------------------------
++ * static irqreturn_t i2c_imx_isr (s16 irq, void * dev_id, struct pt_regs *
++ * reg)
++ * This function deals with the interrupt for the I2C module.
++ *
++ * Parameters: irq the interrupt number
++ * dev_id device id
++ * reg processor register
++ * Return: IRQ_HANDLED the own irq was handled
++ *---------------------------------------------------------------------------*/
++static irqreturn_t i2c_imx_isr (s16 irq, void *dev_id, struct pt_regs * reg)
++{
++ /* safe status register */
++ i2c_imx_i2sr = i2c_imx_reg->i2sr;
++
++ /* if data transfer is complete set ok */
++ if (i2c_imx_i2sr & (u32)0x80) /* [I2SR:ICF] TX complete */
++ i2c_imx_irq_ok = 1;
++
++ /* clear irq */
++ i2c_imx_reg->i2sr &= ~(u32)0x02; /* clear [I2SR:IIF] Interrupt */
++
++ return IRQ_HANDLED;
++}
++
++/*-----------------------------------------------------------------------------
++ * int i2c_imx_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[ ],
++ * SINT16 num)
++ * This function is responsible for the transfer of the data through the
++ * I2C bus
++ *
++ * Parameter: i2c_adap associated with the related hardware
++ * msgs[ ] the body of the message to be send out
++ * num number of message
++ * Return: Success Number of message has been transferred
++ * Failure -err (error code)
++ *---------------------------------------------------------------------------*/
++static int i2c_imx_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[],
++ int num)
++{
++ int i;
++ int count = 0;
++ int err = 0;
++
++ for(i = 0; i < num; i++)
++ I2C_DBG("i2c_adap.%d %s: msg: %d, len: %d, dir: %s, address: "
++ "0x%x\n", i2c_imx_adapter.nr, __FUNCTION__, i,
++ msgs[i].len, (msgs[i].flags & I2C_M_RD)?"rd":"wr",
++ msgs[i].addr);
++
++#ifdef I2C_IMX_SLAVESUPPORT
++ struct i2c_slave *slave = &i2c_imx_slave[msgs[0].addr-1];
++
++ if(slave->address == msgs[0].addr) {
++ unsigned long last_ct = slave->last_ct;
++ int slp_time = slave->slp_time;
++ int slp = slp_time * HZ / 1000 - (jiffies - last_ct);
++ DECLARE_WAIT_QUEUE_HEAD(wait);
++
++ // scheduler: sleep while slave not ready
++ if ((slp > 1) && (msgs[0].flags & I2C_M_RD)) {
++ up(&i2c_adap->bus_lock);
++ sleep_on_timeout(&wait, slp);
++ down(&i2c_adap->bus_lock);
++ }
++ }
++#endif
++
++ /* enable the i2c-bus, disable the I2C transmit ACK */
++ if ((err = i2c_imx_bus_busy()) < 0)
++ goto EXIT_FKT;
++ i2c_imx_reg->i2cr |= (u32)0x80;
++ i2c_imx_reg->i2cr |= (u32)0x08;
++
++ for ( i = 0; i < num; i ++)
++ {
++ /* repeat start else start the bus-transfer */
++ if (i)
++ i2c_imx_reg->i2cr |= (u32)0x04;
++ else
++ if ((err = i2c_imx_start()) < 0)
++ goto EXIT_FKT;
++
++ /* enable interrupt, enable master transmit */
++ i2c_imx_reg->i2cr |= (u32)0x40;
++ i2c_imx_reg->i2cr |= (u32)0x10;
++
++ /* write/read data */
++ if (!(msgs[i].flags & I2C_M_RD)) {
++ if ((err = i2c_imx_write(i, &count, &msgs[i])) < 0)
++ goto EXIT_FKT;
++ } else {
++ if ((err = i2c_imx_read(i, &count, &msgs[i])) < 0)
++ goto EXIT_FKT;
++ }
++ }
++
++EXIT_FKT:
++ /* disable i2c bus */
++ i2c_imx_reg->i2cr &= ~((u32)0x20); /* bus stop */
++ i2c_imx_bus_release();
++ i2c_imx_reg->i2cr &= ~((u32)0x80); /* disable I2C */
++
++#ifdef I2C_IMX_SLAVESUPPORT
++ /* define ms to sleep after read from chip */
++ if (!(msgs[0].flags & I2C_M_RD) && (slave->address == msgs[0].addr))
++ slave->slp_time = slave->get_slp_time(&msgs[0]);
++
++ slave->last_ct = jiffies;
++#endif
++ if(err == 0)
++ return count;
++
++ switch (err) {
++ case -I2C_IMX_ERR_RXACK:
++ i2c_imx_errcnt_rxack++;
++ break;
++ case -I2C_IMX_ERR_TXCOMPLETE:
++ i2c_imx_errcnt_txcomplete++;
++ break;
++ case -I2C_IMX_ERR_BUSY:
++ i2c_imx_errcnt_busy++;
++ break;
++ case -I2C_IMX_ERR_GRAB:
++ i2c_imx_errcnt_grab++;
++ break;
++ }
++
++ I2C_ERR("I2C transfer error\n");
++ I2C_ERRCNT
++
++ return err;
++}
++
++/*-----------------------------------------------------------------------------
++ * int i2c_smbus_imx_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[ ],
++ * SINT16 num)
++ * This function is responsible for the transfer of the data through the
++ * I2C-bus
++ *
++ * Parameter : i2c_adap the structure associated with the related hardware
++ * msgs[ ] the body of the message to be send out
++ * num number of message
++ * Return : Success Number of message has been transferred
++ * Failure -1
++ *---------------------------------------------------------------------------*/
++static int i2c_imx_smbus(struct i2c_adapter * adapter, u16 addr,
++ unsigned short flags, char read_write, u8 command,
++ int size, union i2c_smbus_data * data)
++{
++ char msgbuf0[34];
++ char msgbuf1[34];
++ int num = read_write == I2C_SMBUS_READ?2:1;
++ struct i2c_msg msg[2] = {
++ { addr, flags, 1, msgbuf0 },
++ { addr, flags | I2C_M_RD, 10, msgbuf1 }
++ };
++ int i;
++ msgbuf0[0] = command;
++
++ /* select the smbus-command and create the message */
++ switch(size) {
++ case I2C_SMBUS_QUICK:
++ msg[0].len = 0;
++ msg[0].flags=flags|(read_write==I2C_SMBUS_READ)?I2C_M_RD:0;
++ num = 1;
++ break;
++ case I2C_SMBUS_BYTE:
++ if (read_write == I2C_SMBUS_READ) {
++ msg[0].flags = I2C_M_RD | flags;
++ num = 1;
++ }
++ break;
++ case I2C_SMBUS_BYTE_DATA:
++ if (read_write == I2C_SMBUS_READ)
++ msg[1].len = 1;
++ else {
++ msg[0].len = 2;
++ msgbuf0[1] = data->byte;
++ }
++ break;
++ case I2C_SMBUS_WORD_DATA:
++ if (read_write == I2C_SMBUS_READ)
++ msg[1].len = 2;
++ else {
++ msg[0].len=3;
++ msgbuf0[1] = data->word & 0xff;
++ msgbuf0[2] = (data->word >> 8) & 0xff;
++ }
++ break;
++ case I2C_SMBUS_PROC_CALL:
++ num = 2;
++ msg[0].len = 3;
++ msg[1].len = 2;
++ msgbuf0[1] = data->word & 0xff;
++ msgbuf0[2] = (data->word >> 8) & 0xff;
++ break;
++ case I2C_SMBUS_BLOCK_DATA:
++ if (read_write == I2C_SMBUS_READ) {
++ return -I2C_IMX_ERR_SMBUS_XFER;
++ } else {
++ msg[0].len = data->block[0] + 2;
++ if (msg[0].len > 34) {
++ return -I2C_IMX_ERR_SMBUS_XFER;
++ }
++ for (i = 1; i <= msg[0].len; i++)
++ msgbuf0[i] = data->block[i-1];
++ }
++ break;
++ default:
++ return -I2C_IMX_ERR_SMBUS_XFER;
++ }
++
++ /* call the bus access routine */
++ if (i2c_imx_xfer(adapter, msg, num) < 0)
++ return -I2C_IMX_ERR_SMBUS_XFER;
++
++ /* copy the readed bytes to the data-field */
++ if (read_write == I2C_SMBUS_READ)
++ switch(size) {
++ case I2C_SMBUS_BYTE:
++ data->byte = msgbuf0[0];
++ break;
++ case I2C_SMBUS_BYTE_DATA:
++ data->byte = msgbuf1[0];
++ break;
++ case I2C_SMBUS_WORD_DATA:
++ case I2C_SMBUS_PROC_CALL:
++ data->word = msgbuf1[0] | (msgbuf1[1] << 8);
++ break;
++ }
++
++ return 0;
++}
++
++/*-----------------------------------------------------------------------------
++ * int i2c_imx_ioctl(struct i2c_adapter * adapter, unsigned int cmd,
++ * unsigned long arg)
++ * This function control the I2C module itself
++ *
++ * Parameters: Adapter the adapter associated to the I2C module
++ * Cmd IO control command
++ * Arg argument associated with the command
++ * Return : Success 0
++ *---------------------------------------------------------------------------*/
++static int i2c_imx_ioctl(struct i2c_adapter * adapter, unsigned int cmd,
++ unsigned long arg)
++{
++ switch( cmd ) {
++ case I2C_IMX_IO_SET_CLKDIV:
++ I2C_DBG("i2c_adap.%d %s: Set I2C Clock Rate Divider to #0x%02x"
++ "\n", i2c_imx_adapter.nr, __FUNCTION__,
++ (u32)(arg & 0x003f));
++ i2c_imx_reg->ifdr = (u32)(arg & 0x003f);
++ break;
++ case I2C_IMX_IO_GET_CLKDIV:
++ I2C_DBG("i2c_adap.%d %s: Get I2C Clock Rate Divider\n",
++ i2c_imx_adapter.nr, __FUNCTION__);
++ arg = i2c_imx_reg->ifdr & 0x003f;
++ I2C_DBG("i2c_adap.%d %s: I2C Clock Rate Divider is #0x%02x"
++ "\n", i2c_imx_adapter.nr, __FUNCTION__,
++ (unsigned int)arg);
++ break;
++ }
++
++ return 0;
++}
++
++/*-----------------------------------------------------------------------------
++ * u32 i2c_imx_func(struct i2c_adapter *i2c_adap)
++ * This function returns the functionalities the adapter supports
++ *
++ * Parameter: i2c_adap associated with the related hardware
++ * Return: u32 pattern of supported functionalities (i2c.h)
++ *
++ *---------------------------------------------------------------------------*/
++static u32 i2c_imx_func(struct i2c_adapter *adap)
++{
++ return I2C_FUNC_I2C |
++ I2C_FUNC_SMBUS_QUICK |
++ I2C_FUNC_SMBUS_BYTE |
++ I2C_FUNC_SMBUS_BYTE_DATA |
++ I2C_FUNC_SMBUS_WORD_DATA |
++ I2C_FUNC_SMBUS_PROC_CALL |
++ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA;
++}
++
++/*-----------------------------------------------------------------------------
++ * int __init i2c_imx_init(void)
++ * initializes the I2C module in the DBIMX, and registers itself to the
++ * Linux I2C system
++ *
++ * Parameters: None
++ * Return: 0: indicates SUCCESS
++ * -1: indicates FAILURE
++ *---------------------------------------------------------------------------*/
++static int __init i2c_imx_init(void)
++{
++ i2c_imx_dbg = dbg;
++ i2c_imx_clkdiv = clkdiv;
++
++ /* Pin Configuration for I2C:
++ * 2 Pins are available for the I2C-Module. These Pins are multiplexed
++ * with other functions on the device and must be configured for SPI-
++ * Operation.
++ * The Data Direction Bits in the GPIO Data Direction Register Port A
++ * must be set for Output.
++ * The Function Bits in the GPIO In Use Register Port A must be set
++ * for Multiplexed.
++ * Data Direction (DDIR): Output
++ * GPIO-Function (GIUS): SPI-Operation
++ * GPR, PUEN: for Interrupt operations */
++ imx_gpio_mode(PA15_PF_I2C_SDA);
++ imx_gpio_mode(PA16_PF_I2C_SCL);
++
++ /* install the I2C_IMX ISR to the Linux Kernel */
++ if (request_irq(I2C_INT, (void *)i2c_imx_isr, IRQF_DISABLED,
++ "I2C_IMX", "i2c_bus") < 0)
++ return -I2C_IMX_ERR_INIT;
++
++ /* add the I2C adapter/algorithm driver to the linux kernel */
++ if (i2c_add_adapter(&i2c_imx_adapter))
++ return -I2C_IMX_ERR_INIT;
++
++ I2C_DBG("%s, ver.: %s\n", I2C_IMX_DRIVER_DESC, I2C_IMX_DRIVER_VERSION);
++
++ I2C_DBG("New I2C adapter %d found\n", i2c_imx_adapter.nr);
++
++ /* Set clock Freq. */
++ i2c_imx_reg->ifdr = (u32)i2c_imx_clkdiv;
++ I2C_DBG("i2c_adap.%d I2C Clock Rate Divider set to #0x%x\n",
++ i2c_imx_adapter.nr, i2c_imx_clkdiv);
++
++#ifdef I2C_IMX_SLAVESUPPORT
++ /* define ms to sleep after read from chip */
++ I2C_DBG("i2c_adap.%d I2C slave support added\n",
++ i2c_imx_adapter.nr);
++#endif
++
++ return 0;
++}
++
++/*-----------------------------------------------------------------------------
++ * void __exit i2c_imx_cleanup(void)
++ * This routine is called when the driver is unloaded
++ *
++ * Parameters: None
++ * Return: None
++ *---------------------------------------------------------------------------*/
++static void __exit i2c_imx_cleanup(void)
++{
++ I2C_ERRCNT
++
++ I2C_DBG("I2C adapter removed\n");
++
++ /* unset IEN[I2CR:7] (I2C Disable) */
++ i2c_imx_reg->i2cr = (u32)0x00;
++
++ /* Free IRQ */
++ free_irq (I2C_INT, "i2c_bus");
++
++ /* Delete Adapter from Kernel */
++ i2c_del_adapter(&i2c_imx_adapter);
++}
++
++module_init(i2c_imx_init);
++module_exit(i2c_imx_cleanup);
++
++MODULE_AUTHOR(I2C_IMX_DRIVER_AUTHOR);
++MODULE_DESCRIPTION(I2C_IMX_DRIVER_DESC);
++MODULE_LICENSE("GPL");
++
++module_param(dbg, bool, 0);
++MODULE_PARM_DESC(dbg, "Debug enabled or not");
++
++module_param(clkdiv, int, I2C_IMX_DEFAULT_CLKDIV);
++MODULE_PARM_DESC(clkdiv, "I2C Clock Rate Divider");
++
++#ifdef I2C_IMX_SLAVESUPPORT
++EXPORT_SYMBOL(i2c_imx_add_slave);
++EXPORT_SYMBOL(i2c_imx_del_slave);
++#endif
+--- ref/linux-2.6.23/drivers/i2c/busses/i2c-imx.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.23/drivers/i2c/busses/i2c-imx.h 2007-01-14 14:08:26.000000000 +0100
+@@ -0,0 +1,176 @@
++/*
++ * Copyright (C) 2002 Motorola GSG-China
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++ * USA.
++ *
++ * File Name: i2c-imx.h
++ *
++ * Author: Torsten Koschorrek, synertronixx GmbH
++ *
++ * Desc.: Implementation of I2C Adapter/Algorithm Driver
++ *
++ * Derived from Motorola GSG China I2C example driver
++ *
++ * Copyright (C) 2002 Motorola GSG-China
++ * Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de>
++ * Portions:
++ * Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de>
++ *
++ * History: 2002/2/07 use msgs[]
++ * Motorola GSG-China
++ * 2004/3/03 port to linux kernel v2.6.x for i.MX
++ * adding ioctl (change bus freq)
++ * adding cpu- and bus-usage optimization (..slp)
++ * T. Koschorrek <koschorrek at synertronixx.de>
++ * 2005/2/28 changes in timings
++ * M. Blaschke <blaschke at synertronixx.de>
++ * 2005/6/01 added module parameters, cleaning up, cpu- and bus-usage
++ * modularized (..slave)
++ * T. Koschorrek <koschorrek at synertronixx.de>
++ * 2007/1/14 fix i2c_imx_read/write to return number of messages
++ * processed.
++ * Change form for compatibility with kernel > 2.6.18.
++ * Change default CLKDIV to 0x0F (400kHz i2c / 96MHz HCLK).
++ * Jorasse <jo...@us...>
++ */
++
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++
++#include <asm/arch/irqs.h>
++#include <asm/arch/hardware.h>
++
++#define I2C_IMX_DRIVER_VERSION "14 January 2007"
++#define I2C_IMX_DRIVER_AUTHOR "T. Koschorrek, synertronixx GmbH"
++#define I2C_IMX_DRIVER_DESC "I2C Adapter/Algorithm driver"
++
++#define I2C_IMX_DEFAULT_DEBUG 0
++#define I2C_IMX_DEFAULT_CLKDIV 16 // 0x0f
++
++#define I2C_IMX_TIME_GRAB 2000
++#define I2C_IMX_TIME_BUSY 2000
++#define I2C_IMX_TIME_RELEASE 2000
++#define I2C_IMX_TIME_TXCOMPLETE 2000
++#define I2C_IMX_MAX_GRAB 3
++
++#define I2C_IMX_IO_SET_CLKDIV 0xaa
++#define I2C_IMX_IO_GET_CLKDIV 0xab
++
++#define I2C_IMX_ERR_INIT 0x01
++#define I2C_IMX_ERR_SMBUS_XFER 0x02
++#define I2C_IMX_ERR_RXACK 0x03
++#define I2C_IMX_ERR_TXCOMPLETE 0x04
++#define I2C_IMX_ERR_BUSY 0x05
++#define I2C_IMX_ERR_GRAB 0x06
++
++
++
++#ifdef I2C_IMX_SLAVESUPPORT
++#include "i2c-imx-slave.h"
++#endif
++
++
++
++/* function declarations */
++static int i2c_imx_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[ ],
++ int num);
++static int i2c_imx_smbus(struct i2c_adapter * adapter, u16 addr,
++ unsigned short flags, char read_write, u8 command,
++ int size, union i2c_smbus_data * data);
++static int i2c_imx_ioctl(struct i2c_adapter * adapter, unsigned int cmd,
++ unsigned long arg);
++static u32 i2c_imx_func(struct i2c_adapter *adap);
++
++/* structs */
++static struct i2c_algorithm i2c_imx_algorithm = {
++ .master_xfer = i2c_imx_xfer,
++ .smbus_xfer = i2c_imx_smbus,
++ .algo_control = i2c_imx_ioctl,
++ .functionality = i2c_imx_func
++};
++
++static struct i2c_adapter i2c_imx_adapter = {
++ .owner = THIS_MODULE,
++ .name = "IMX I2C adapter",
++ .class = I2C_CLASS_HWMON,
++ .algo = &i2c_imx_algorithm
++};
++
++struct i2c_regs {
++ /* address reg */ volatile u32 iadr;
++ /* freq div. reg */ volatile u32 ifdr;
++ /* control reg */ volatile u32 i2cr;
++ /* status reg */ volatile u32 i2sr;
++ /* data io reg */ volatile u32 i2dr;
++};
++
++
++
++
++/* global variables */
++static struct i2c_regs *i2c_imx_reg = (struct i2c_regs *)IMX_I2C_BASE;
++static spinlock_t i2c_imx_irqlock = SPIN_LOCK_UNLOCKED;
++static int i2c_imx_irq_ok;
++static int i2c_imx_i2sr;
++
++#ifdef I2C_IMX_SLAVESUPPORT
++static struct i2c_slave i2c_imx_slave[128];
++#endif
++
++int i2c_imx_errcnt_rxack = 0;
++int i2c_imx_errcnt_txcomplete = 0;
++int i2c_imx_errcnt_busy = 0;
++int i2c_imx_errcnt_grab = 0;
++
++int dbg = I2C_IMX_DEFAULT_DEBUG;
++int i2c_imx_dbg = I2C_IMX_DEFAULT_DEBUG;
++int clkdiv = I2C_IMX_DEFAULT_CLKDIV;
++int i2c_imx_clkdiv = I2C_IMX_DEFAULT_CLKDIV;
++
++
++
++
++/* debug messages */
++#ifdef DEBUG
++#define I2C_DBG(stuff ...) { \
++ if (i2c_imx_dbg) { \
++ printk(KERN_NOTICE stuff); \
++ } \
++ }
++#define I2C_ERR(stuff ...) { \
++ if (i2c_imx_dbg) { \
++ printk(KERN_ERR "i2c_adap.%d ", i2c_imx_adapter.nr);\
++ printk(stuff); \
++ } \
++ }
++#else
++#define I2C_DBG(stuff ...) while(0){}
++#define I2C_ERR(stuff ...) while(0){}
++#endif
++
++#ifdef DEBUG
++#define I2C_ERRCNT { \
++ I2C_ERR(" RX ACK : %d Error(s)\n", i2c_imx_errcnt_rxack); \
++ I2C_ERR(" TX COMPLETE: %d Error(s)\n", i2c_imx_errcnt_txcomplete);\
++ I2C_ERR(" BUS BUSY : %d Error(s)\n", i2c_imx_errcnt_busy); \
++ I2C_ERR(" BUS GRAB : %d Error(s)\n", i2c_imx_errcnt_grab); \
++}
++#else
++#define I2C_ERRCNT
++#endif
+--- ref/linux-2.6.23/drivers/i2c/busses/Kconfig 2006-10-14 05:34:03.000000000 +0200
++++ linux-2.6.23/drivers/i2c/busses/Kconfig 2007-01-14 00:35:15.000000000 +0100
+@@ -521,6 +521,11 @@ config I2C_PCA_ISA
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-pca-isa.
++config I2C_IMX
++ tristate "i2c bus on i.MX"
++ depends on I2C
++ help
++ i2c implenentation on i.MX motorola prozessors
+
+ This device is almost undetectable and using this driver on a
+ system which doesn't have this device will result in long
+--- ref/linux-2.6.23/drivers/i2c/busses/Makefile 2006-10-14 05:34:03.000000000 +0200
++++ linux-2.6.23/drivers/i2c/busses/Makefile 2007-01-14 00:35:15.000000000 +0100
+@@ -41,6 +41,7 @@ obj-$(CONFIG_I2C_STUB) += i2c-stub.o
+ obj-$(CONFIG_I2C_VIA) += i2c-via.o
+ obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
+ obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o
++obj-$(CONFIG_I2C_IMX) += i2c-imx.o
+ obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
+ obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|