[Armadeus-commitlog] SF.net SVN: armadeus:[1139] trunk/target/linux/modules/gpio
Brought to you by:
sszy
|
From: <ar...@us...> - 2009-03-10 14:32:33
|
Revision: 1139
http://armadeus.svn.sourceforge.net/armadeus/?rev=1139&view=rev
Author: artemys
Date: 2009-03-10 14:32:12 +0000 (Tue, 10 Mar 2009)
Log Message:
-----------
[LINUX] Cleanup in gpio driver: kernel friendly indentation, removing of unused code
Modified Paths:
--------------
trunk/target/linux/modules/gpio/Kconfig
trunk/target/linux/modules/gpio/core.c
trunk/target/linux/modules/gpio/ppdevemu.c
Removed Paths:
-------------
trunk/target/linux/modules/gpio/ppdevemu.h
Modified: trunk/target/linux/modules/gpio/Kconfig
===================================================================
--- trunk/target/linux/modules/gpio/Kconfig 2009-03-10 12:50:55 UTC (rev 1138)
+++ trunk/target/linux/modules/gpio/Kconfig 2009-03-10 14:32:12 UTC (rev 1139)
@@ -8,9 +8,9 @@
---help---
config ARMADEUS_PPDEV_DRIVER
- tristate "Armadeus Parallel Port driver"
+ tristate "Armadeus Parallel Port emulation driver (with LCD port)"
default n
- depends on ARMADEUS_GPIO_DRIVER
+ depends on ARMADEUS_GPIO_DRIVER && MACH_APF9328
---help---
This driver allows you to emulate a parallel port interface with GPIO.
- Activate it if you want for example connect a LCD with a // port interface.
\ No newline at end of file
+ Activate it if you want for example connect a LCD with a // port interface.
Modified: trunk/target/linux/modules/gpio/core.c
===================================================================
--- trunk/target/linux/modules/gpio/core.c 2009-03-10 12:50:55 UTC (rev 1138)
+++ trunk/target/linux/modules/gpio/core.c 2009-03-10 14:32:12 UTC (rev 1139)
@@ -56,7 +56,7 @@
#define FULL_MINOR_TO_PORT(x) (MAX_MINOR - x)
-// Parameters order:
+/* Parameters order: */
enum {
DDIR_I = 0,
OCR1_I,
@@ -76,7 +76,7 @@
PUEN_I,
};
-// Global variables
+/* Global variables */
struct gpio_operations *driver_ops;
static int gpio_major = GPIO_MAJOR;
@@ -97,7 +97,7 @@
int type;
};
-// Module parameters
+/* 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 };
static int portA_init_nb = 0;
@@ -134,28 +134,29 @@
int id;
struct class_device *gpio_dev;
struct cdev char_dev;
-// struct config_item item; TBDJUJU: Use configfs filesystem !
+ /* struct config_item item; TBDJUJU: Use configfs filesystem ! */
};
static unsigned int shadows_irq[NB_PORTS] = { 0, 0, 0, 0 };
-// Static functions
+/* 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;
+ 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 */
@@ -166,8 +167,7 @@
ret_val = 0;
/* Create WORD to write from the string */
- for( i=0, j=1; j<=number_of_bits; i++)
- {
+ 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 */
@@ -180,162 +180,91 @@
}
}
- return(ret_val);
+ return ret_val;
}
-//------------------------------------------------
-//
-// Low level functions
-//
+/*
+ * Low level functions
+ */
#define DEFAULT_VALUE 0x12345678
-// These masks are for restricting user access 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
#define PORT_C_MASK 0x0003E1F8
#define PORT_D_MASK 0xFFFFFFFF
-static void initializePortA( void )
+static void initialize_port(int port, int* init_params)
{
- unsigned long lTemp;
-
- // Initialize PORTA with module parameters
- if( portA_init[DR_I] != 0 ) { DR(PORT_A) = portA_init[DR_I]; }
- if( portA_init[SSR_I] != 0 ) { SSR(PORT_A) = portA_init[SSR_I]; }
- if( portA_init[OCR1_I] != 0 ) { OCR1(PORT_A) = portA_init[OCR1_I]; } /*else { default value are already set by iMX !!*/
- if( portA_init[OCR2_I] != 0 ) { OCR2(PORT_A) = portA_init[OCR2_I]; }
- if( portA_init[ICONFA1_I] != 0 ) { ICONFA1(PORT_A) = portA_init[ICONFA1_I]; }
- if( portA_init[ICONFA2_I] != 0 ) { ICONFA2(PORT_A) = portA_init[ICONFA2_I]; }
- if( portA_init[ICONFB1_I] != 0 ) { ICONFB1(PORT_A) = portA_init[ICONFB1_I]; }
- if( portA_init[ICONFB2_I] != 0 ) { ICONFB2(PORT_A) = portA_init[ICONFB2_I]; }
- if( portA_init[DDIR_I] != 0 ) { DDIR(PORT_A) = portA_init[DDIR_I]; }
- if( portA_init[SWR_I] != 0 ) { SWR(PORT_A) = portA_init[SWR_I]; }
- if( portA_init[GPR_I] != 0 ) { lTemp = GPR(PORT_A) & (~MASK[PORT_A]); GPR(PORT_A) = lTemp | (portA_init[GPR_I] & MASK[PORT_A]); }
- if( portA_init[GIUS_I] != 0 ) { lTemp = GIUS(PORT_A) & (~MASK[PORT_A]); GIUS(PORT_A) = lTemp | (portA_init[GIUS_I] & MASK[PORT_A]); }
- if( portA_init[PUEN_I] != 0 ) { lTemp = PUEN(PORT_A) & (~MASK[PORT_A]); PUEN(PORT_A) = lTemp | (portA_init[PUEN_I] & MASK[PORT_A]); }
- if( portA_init[ICR1_I] != 0 ) { ICR1(PORT_A) = portA_init[ICR1_I]; }
- if( portA_init[ICR2_I] != 0 ) { ICR2(PORT_A) = portA_init[ICR2_I]; }
- if( portA_init[IMR_I] != 0 ) { IMR(PORT_A) = portA_init[IMR_I]; }
+ unsigned long lTemp;
+
+ /* Initialize PORT with module parameters */
+ if (init_params[DR_I]) { DR(port) = init_params[DR_I]; }
+ if (init_params[SSR_I]) { SSR(port) = init_params[SSR_I]; }
+ if (init_params[OCR1_I]) { OCR1(port) = init_params[OCR1_I]; }
+ /*else { default value are already set by iMX !!*/
+ if (init_params[OCR2_I]) { OCR2(port) = init_params[OCR2_I]; }
+ if (init_params[ICONFA1_I]) { ICONFA1(port) = init_params[ICONFA1_I]; }
+ if (init_params[ICONFA2_I]) { ICONFA2(port) = init_params[ICONFA2_I]; }
+ if (init_params[ICONFB1_I]) { ICONFB1(port) = init_params[ICONFB1_I]; }
+ if (init_params[ICONFB2_I]) { ICONFB2(port) = init_params[ICONFB2_I]; }
+ if (init_params[DDIR_I]) { DDIR(port) = init_params[DDIR_I]; }
+ if (init_params[SWR_I]) { SWR(port) = init_params[SWR_I]; }
+ if (init_params[GPR_I]) { lTemp = GPR(port) & (~MASK[port]); GPR(port) = lTemp | (init_params[GPR_I] & MASK[port]); }
+ if (init_params[GIUS_I]) { lTemp = GIUS(port) & (~MASK[port]); GIUS(port) = lTemp | (init_params[GIUS_I] & MASK[port]); }
+ if (init_params[PUEN_I]) { lTemp = PUEN(port) & (~MASK[port]); PUEN(port) = lTemp | (init_params[PUEN_I] & MASK[port]); }
+ if (init_params[ICR1_I]) { ICR1(port) = init_params[ICR1_I]; }
+ if (init_params[ICR2_I]) { ICR2(port) = init_params[ICR2_I]; }
+ if (init_params[IMR_I]) { IMR(port) = init_params[IMR_I]; }
}
-static void initializePortB( void )
+static void initialize_all_ports( void )
{
- unsigned long lTemp;
-
- // Initialize PORTB with module parameters
- if( portB_init[DR_I] != 0 ) { DR(PORT_B) = portB_init[DR_I]; }
- if( portB_init[SSR_I] != 0 ) { SSR(PORT_B) = portB_init[SSR_I]; }
- if( portB_init[OCR1_I] != 0 ) { OCR1(PORT_B) = portB_init[OCR1_I]; } /*else { default value are already set by iMX !!*/
- if( portB_init[OCR2_I] != 0 ) { OCR2(PORT_B) = portB_init[OCR2_I]; }
- if( portB_init[ICONFA1_I] != 0 ) { ICONFA1(PORT_B) = portB_init[ICONFA1_I]; }
- if( portB_init[ICONFA2_I] != 0 ) { ICONFA2(PORT_B) = portB_init[ICONFA2_I]; }
- if( portB_init[ICONFB1_I] != 0 ) { ICONFB1(PORT_B) = portB_init[ICONFB1_I]; }
- if( portB_init[ICONFB2_I] != 0 ) { ICONFB2(PORT_B) = portB_init[ICONFB2_I]; }
- if( portB_init[DDIR_I] != 0 ) { DDIR(PORT_B) = portB_init[DDIR_I]; }
- if( portB_init[SWR_I] != 0 ) { SWR(PORT_B) = portB_init[SWR_I]; }
- if( portB_init[GPR_I] != 0 ) { lTemp = GPR(PORT_B) & (~MASK[PORT_B]); GPR(PORT_B) = lTemp | (portB_init[GPR_I] & MASK[PORT_B]); }
- if( portB_init[GIUS_I] != 0 ) { lTemp = GIUS(PORT_B) & (~MASK[PORT_B]); GIUS(PORT_B) = lTemp | (portB_init[GIUS_I] & MASK[PORT_B]); }
- if( portB_init[PUEN_I] != 0 ) { lTemp = PUEN(PORT_B) & (~MASK[PORT_B]); PUEN(PORT_B) = lTemp | (portB_init[PUEN_I] & MASK[PORT_B]); }
- if( portB_init[ICR1_I] != 0 ) { ICR1(PORT_B) = portB_init[ICR1_I]; }
- if( portB_init[ICR2_I] != 0 ) { ICR2(PORT_B) = portB_init[ICR2_I]; }
- if( portB_init[IMR_I] != 0 ) { IMR(PORT_B) = portB_init[IMR_I]; }
+ initialize_port(PORT_A, portA_init);
+ initialize_port(PORT_B, portB_init);
+ initialize_port(PORT_C, portC_init);
+ initialize_port(PORT_D, portD_init);
}
-static void initializePortC( void )
-{
- unsigned long lTemp;
- // Initialize PORTC with module parameters
- if( portC_init[DR_I] != 0 ) { DR(PORT_C) = portC_init[DR_I]; }
- if( portC_init[SSR_I] != 0 ) { SSR(PORT_C) = portC_init[SSR_I]; }
- if( portC_init[OCR1_I] != 0 ) { OCR1(PORT_C) = portC_init[OCR1_I]; } /*else { default value are already set by iMX !!*/
- if( portC_init[OCR2_I] != 0 ) { OCR2(PORT_C) = portC_init[OCR2_I]; }
- if( portC_init[ICONFA1_I] != 0 ) { ICONFA1(PORT_C) = portC_init[ICONFA1_I]; }
- if( portC_init[ICONFA2_I] != 0 ) { ICONFA2(PORT_C) = portC_init[ICONFA2_I]; }
- if( portC_init[ICONFB1_I] != 0 ) { ICONFB1(PORT_C) = portC_init[ICONFB1_I]; }
- if( portC_init[ICONFB2_I] != 0 ) { ICONFB2(PORT_C) = portC_init[ICONFB2_I]; }
- if( portC_init[DDIR_I] != 0 ) { DDIR(PORT_C) = portC_init[DDIR_I]; }
- if( portC_init[SWR_I] != 0 ) { SWR(PORT_C) = portC_init[SWR_I]; }
- if( portC_init[GPR_I] != 0 ) { lTemp = GPR(PORT_C) & (~MASK[PORT_C]); GPR(PORT_C) = lTemp | (portC_init[GPR_I] & MASK[PORT_C]); }
- if( portC_init[GIUS_I] != 0 ) { lTemp = GIUS(PORT_C) & (~MASK[PORT_C]); GIUS(PORT_C) = lTemp | (portC_init[GIUS_I] & MASK[PORT_C]); }
- if( portC_init[PUEN_I] != 0 ) { lTemp = PUEN(PORT_C) & (~MASK[PORT_C]); PUEN(PORT_C) = lTemp | (portC_init[PUEN_I] & MASK[PORT_C]); }
- if( portC_init[ICR1_I] != 0 ) { ICR1(PORT_C) = portC_init[ICR1_I]; }
- if( portC_init[ICR2_I] != 0 ) { ICR2(PORT_C) = portC_init[ICR2_I]; }
- if( portC_init[IMR_I] != 0 ) { IMR(PORT_C) = portC_init[IMR_I]; }
-}
+/* TBDJUJU: replace the following functions with imx_gpio_xxx one !! */
-static void initializePortD( void )
+static void writeOnPort( unsigned int aPort, unsigned int aValue )
{
- unsigned long lTemp;
-
- // Initialize PORTD with module parameters
- if( portD_init[DR_I] != 0 ) { DR(PORT_D) = portD_init[DR_I]; }
- if( portD_init[SSR_I] != 0 ) { SSR(PORT_D) = portD_init[SSR_I]; }
- if( portD_init[OCR1_I] != 0 ) { OCR1(PORT_D) = portD_init[OCR1_I]; } /*else { default value are already set by iMX !!*/
- if( portD_init[OCR2_I] != 0 ) { OCR2(PORT_D) = portD_init[OCR2_I]; }
- if( portD_init[ICONFA1_I] != 0 ) { ICONFA1(PORT_D) = portD_init[ICONFA1_I]; }
- if( portD_init[ICONFA2_I] != 0 ) { ICONFA2(PORT_D) = portD_init[ICONFA2_I]; }
- if( portD_init[ICONFB1_I] != 0 ) { ICONFB1(PORT_D) = portD_init[ICONFB1_I]; }
- if( portD_init[ICONFB2_I] != 0 ) { ICONFB2(PORT_D) = portD_init[ICONFB2_I]; }
- if( portD_init[DDIR_I] != 0 ) { DDIR(PORT_D) = portD_init[DDIR_I]; }
- if( portD_init[SWR_I] != 0 ) { SWR(PORT_D) = portD_init[SWR_I]; }
- if( portD_init[GPR_I] != 0 ) { lTemp = GPR(PORT_D) & (~MASK[PORT_D]); GPR(PORT_D) = lTemp | (portD_init[GPR_I] & MASK[PORT_D]); }
- if( portD_init[GIUS_I] != 0 ) { lTemp = GIUS(PORT_D) & (~MASK[PORT_D]); GIUS(PORT_D) = lTemp | (portD_init[GIUS_I] & MASK[PORT_D]); }
- if( portD_init[PUEN_I] != 0 ) { lTemp = PUEN(PORT_D) & (~MASK[PORT_D]); PUEN(PORT_D) = lTemp | (portD_init[PUEN_I] & MASK[PORT_D]); }
- if( portD_init[ICR1_I] != 0 ) { ICR1(PORT_D) = portD_init[ICR1_I]; }
- if( portD_init[ICR2_I] != 0 ) { ICR2(PORT_D) = portD_init[ICR2_I]; }
- if( portD_init[IMR_I] != 0 ) { IMR(PORT_D) = portD_init[IMR_I]; }
+ DR(aPort) = (aValue & MASK[aPort]);
}
-static void initializePorts( void )
+static unsigned int readFromPort( unsigned int aPort )
{
- initializePortA();
- initializePortB();
- initializePortC();
- initializePortD();
-}
+ unsigned int port_value = 0;
+ /* Get the status of the gpio ports */
+ port_value = (SSR(aPort));
-// TBDJUJU: replace the following functions with imx_gpio_xxx one !!
-
-static void writeOnPort( unsigned int aPort, unsigned int aValue )
-{
- //
- DR(aPort) = (aValue & MASK[aPort]);
+ return( port_value );
}
-static unsigned int readFromPort( unsigned int aPort )
-{
- unsigned int port_value = 0;
-
- // Get the status of the gpio ports
- port_value = (SSR(aPort));
-
- return( port_value );
-}
-
static void setPortDir( unsigned int aPort, unsigned int aDirMask )
{
- DDIR(aPort) = (aDirMask & 0xffffffff);
+ DDIR(aPort) = (aDirMask & 0xffffffff);
}
static unsigned int getPortDir( unsigned int aPort )
{
- unsigned int port_value = 0;
-
- // Get the status of the gpio direction registers TBDNICO
- port_value = (DDIR(aPort));
-
- return( port_value );
+ unsigned int port_value = 0;
+
+ /* Get the status of the gpio direction registers TBDNICO */
+ port_value = (DDIR(aPort));
+
+ 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
-//
+
+/* Handles write() done on /dev/gpioxx */
static ssize_t armadeus_gpio_dev_write(struct file *file, const char *data, size_t count, loff_t *offset)
{
unsigned int minor=0;
@@ -367,27 +296,27 @@
ret = count;
out:
- up(&gpio_sema);
- return ret;
+ up(&gpio_sema);
+ return ret;
}
-//
-// Handles read() done on /dev/gpioxx
-//
-static ssize_t armadeus_gpio_dev_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+/* Handles read() done on /dev/gpioxx */
+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);
- u32 value=0;
- ssize_t ret = 0;
- u32 port_status;
+ unsigned minor = MINOR(file->f_dentry->d_inode->i_rdev);
+ u32 value=0;
+ ssize_t ret = 0;
+ u32 port_status;
struct gpio_item *gpio = file->private_data;
- if (count == 0)
- return count;
+ if (count == 0)
+ return count;
spin_lock_irq(&gpio->lock);
- pr_debug("- %s %d byte(s) on minor %d -> %s pin %d\n", __FUNCTION__, count, minor, port_name[gpio->port], gpio->number);
+ pr_debug("- %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);
@@ -402,7 +331,7 @@
}
gpio->changed = 0;
- if( gpio->nb_pins != 1) {
+ if (gpio->nb_pins != 1) {
value = readFromPort( gpio->port );
pr_debug("Full port read: 0x%x\n", value);
} else {
@@ -410,19 +339,19 @@
pr_debug("Single pin read: %d\n", value);
}
- value = readFromPort( minor );
- port_status = (char)(value & 0xFF);
+ value = readFromPort( minor );
+ port_status = (char)(value & 0xFF);
count = min( count, (size_t)sizeof(u32) );
- if ( copy_to_user(buf, &value, count) ) {
- ret = -EFAULT;
- goto out;
- }
- ret = count;
+ if (copy_to_user(buf, &value, count)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ ret = count;
out:
- spin_unlock_irq(&gpio->lock);
- return ret;
+ spin_unlock_irq(&gpio->lock);
+ return ret;
}
@@ -448,12 +377,10 @@
return IRQ_HANDLED;
}
-//
-// Handles open() done on /dev/gpioxx
-//
+/* Handles open() done on /dev/gpioxx */
static int armadeus_gpio_dev_open(struct inode *inode, struct file *file)
{
- unsigned minor = MINOR(inode->i_rdev);
+ unsigned minor = MINOR(inode->i_rdev);
unsigned int major = MAJOR(inode->i_rdev);
unsigned int irq;
int ret = 0;
@@ -468,7 +395,7 @@
spin_lock_init(&gpio->lock);
init_waitqueue_head(&gpio->change_wq);
- switch(minor)
+ switch (minor)
{
/* Write all port pins in one time */
case FULL_PORTA_MINOR:
@@ -507,7 +434,7 @@
ret = request_irq( irq, armadeus_gpio_interrupt, 0, "gpio", gpio );
if( ret )
goto err_irq;
-// set_irq_type( irq, IRQF_TRIGGER_FALLING ); TDBJUJU
+ /* set_irq_type( irq, IRQF_TRIGGER_FALLING ); TDBJUJU */
}
success:
@@ -524,9 +451,7 @@
return ret;
}
-//
-// Handles close() done on /dev/gpioxx
-//
+/* Handles close() done on /dev/gpioxx */
static int armadeus_gpio_dev_release(struct inode *inode, struct file *file)
{
unsigned minor = MINOR(inode->i_rdev);
@@ -546,91 +471,93 @@
return 0;
}
-//------------------------------------------------
-// Handling of IOCTL calls
-//
-int armadeus_gpio_dev_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg )
+/* Handling of IOCTL calls */
+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;
- unsigned int minor;
-
- printk( 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) != PP_IOCTL) return -ENOTTY;
+ int err = 0; int ret = 0;
+ int value=0;
+ unsigned int minor;
- // 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));
+ printk( DRIVER_NAME " ## IOCTL received: (0x%x) ##\n", cmd );
- if (err) return -EFAULT;
+ /* Extract the type and number bitfields, and don't decode wrong cmds:
+ return ENOTTY (inappropriate ioctl) before access_ok() */
+ if (_IOC_TYPE(cmd) != PP_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));
- // Obtain exclusive access
- if (down_interruptible(&gpio_sema))
- return -ERESTARTSYS;
- // Extract and test minor
- minor = MINOR(inode->i_rdev);
- if( minor < FULL_PORTD_MINOR ) {
- printk("Minor outside range: %d !\n", minor);
- return -EFAULT;
- }
-
- switch(cmd)
- {
- case GPIORDDIRECTION:
- value = getPortDir( minor );
- ret = __put_user(value, (unsigned int *)arg);
- break;
+ if (err) return -EFAULT;
- case GPIOWRDIRECTION:
- ret = __get_user(value, (unsigned int *)arg);
+ /* Obtain exclusive access */
+ if (down_interruptible(&gpio_sema))
+ return -ERESTARTSYS;
+ /* Extract and test minor */
+ minor = MINOR(inode->i_rdev);
+ if (minor < FULL_PORTD_MINOR) {
+ printk("Minor outside range: %d !\n", minor);
+ return -EFAULT;
+ }
- if( ret==0 ) {
- setPortDir( minor, value );
- }
- break;
-
- case GPIORDDATA:
- value = readFromPort( minor );
- ret = __put_user(value, (unsigned int *)arg);
- break;
-
- case GPIOWRDATA:
- ret = __get_user(value, (unsigned int *)arg);
- if( ret == 0 ) {
- writeOnPort( minor, value );
- }
- break;
-
- default:
- return -ENOTTY;
- break;
- }
- // Release exclusive access
- up(&gpio_sema);
-
- return ret;
+ switch(cmd)
+ {
+ case GPIORDDIRECTION:
+ value = getPortDir( minor );
+ ret = __put_user(value, (unsigned int *)arg);
+ break;
+
+ case GPIOWRDIRECTION:
+ ret = __get_user(value, (unsigned int *)arg);
+
+ if (ret==0) {
+ setPortDir( minor, value );
+ }
+ break;
+
+ case GPIORDDATA:
+ value = readFromPort( minor );
+ ret = __put_user(value, (unsigned int *)arg);
+ break;
+
+ case GPIOWRDATA:
+ ret = __get_user(value, (unsigned int *)arg);
+ if (ret == 0) {
+ writeOnPort( minor, value );
+ }
+ break;
+
+ default:
+ return -ENOTTY;
+ break;
+ }
+ /* Release exclusive access */
+ up(&gpio_sema);
+
+ return ret;
}
-//------------------------------------------------
-// PROC file functions
-//
+/*
+ * PROC file functions
+ */
-static int armadeus_gpio_proc_read( char *buffer, char **start, off_t offset, int buffer_length, int *eof, __attribute__ ((unused)) void *data )
+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;
+ 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;
- }
+ 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
@@ -638,11 +565,11 @@
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 (offset > 0 || buffer_length < (number_of_pins[port_ID]+2))
+ return 0;
- if (down_interruptible(&gpio_sema))
- return -ERESTARTSYS;
+ if (down_interruptible(&gpio_sema))
+ return -ERESTARTSYS;
switch( settings->type )
{
@@ -651,7 +578,7 @@
break;
case DIRECTION:
- // Get the status of the gpio direction registers TBDNICO
+ /* Get the status of the gpio direction registers TBDNICO */
printk("direction\n");
port_status = getPortDir(port_ID);
break;
@@ -674,11 +601,11 @@
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;
+ *eof = 1;
+ up(&gpio_sema);
+
+ /* Return the length */
+ return len;
}
static char new_gpio_state[MAX_NUMBER_OF_PINS*2];
@@ -690,36 +617,36 @@
unsigned int port_ID = 0;
struct gpio_settings *settings = (struct gpio_settings *) data;
- if( settings != NULL ) {
+ if (settings != NULL) {
port_ID = settings->port;
}
- /* Do some checks on parameters */
- if( count <= 0 ) {
- printk("Empty string transmitted !\n");
- return 0;
- }
+ /* 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)) ) {
+ 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 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;
- }
+ /* 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
+ /* Convert it from String to Int */
gpio_state = fromString( new_gpio_state, number_of_pins[port_ID] );
switch( settings->type )
@@ -748,11 +675,14 @@
break;
}
- printk("/proc wrote 0x%x on %s %s register\n", gpio_state, port_name[port_ID], port_setting_name[settings->type]);
+ 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 */
+ up(&gpio_sema);
+ /* Makes as if we take all the data sent even if we can't handle more
+ than register size */
+ return count;
}
@@ -768,10 +698,10 @@
{
int i;
- for( i=0; i<4; 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 ) {
+ if (config[i].entry == NULL) {
printk(KERN_ERR DRIVER_NAME ": Couldn't register %s. Terminating.\n", config[i].name);
return -ENOMEM;
}
@@ -789,17 +719,17 @@
/*
* Create /proc entries for direct access (with echo/cat) to GPIOs config
*/
-static int create_proc_entries( void )
+static int create_proc_entries(void)
{
struct proc_config_entry proc_config[NB_PORTS];
int ret;
- printk("Creating /proc entries: ");
+ printk("Creating /proc entries: ");
- /* Create main directory */
- proc_mkdir(GPIO_PROC_DIRNAME, NULL);
+ /* Create main directory */
+ proc_mkdir(GPIO_PROC_DIRNAME, NULL);
- /* Create proc file to handle GPIO values */
+ /* 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;
@@ -809,11 +739,11 @@
proc_config[PORT_D].name = GPIO_PROC_PORTD_FILENAME;
proc_config[PORT_D].type = VALUE;
- if( (ret = initialize_entry(proc_config)) )
+ if ((ret = initialize_entry(proc_config)))
return ret;
init_map |= GPIO_PROC_FILE;
- /* Create proc file to handle GPIO direction settings */
+ /* 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;
@@ -823,7 +753,7 @@
proc_config[PORT_D].name = GPIO_PROC_PORTDDIR_FILENAME;
proc_config[PORT_D].type = DIRECTION;
- if( (ret = initialize_entry(proc_config)) )
+ if ((ret = initialize_entry(proc_config)))
return ret;
init_map |= SETTINGS_PROC_FILE;
@@ -837,7 +767,7 @@
proc_config[PORT_D].name = GPIO_PROC_PORTD_IRQ_FILENAME;
proc_config[PORT_D].type = INTERRUPT;
- if( (ret = initialize_entry(proc_config)) )
+ if ((ret = initialize_entry(proc_config)))
return ret;
init_map |= SETTINGS_IRQ_PROC_FILE;
@@ -851,126 +781,114 @@
proc_config[PORT_D].name = GPIO_PROC_PORTD_PULLUP_FILENAME;
proc_config[PORT_D].type = PULL_UP;
- if( (ret = initialize_entry(proc_config)) )
+ if ((ret = initialize_entry(proc_config)))
return ret;
init_map |= SETTINGS_PULLUP_PROC_FILE;
- printk("OK!\n");
- return(0);
+ printk("OK!\n");
+ return(0);
}
-//
-// /dev functionnalities supported:
-//
+static void remove_proc_entries(void)
+{
+ /* Remove /proc entries */
+ if (init_map & GPIO_PROC_FILE) {
+ printk( DRIVER_NAME " removing " GPIO_PROC_PORTA_FILENAME " & Co\n" );
+ remove_proc_entry( GPIO_PROC_PORTA_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTB_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTC_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTD_FILENAME, NULL);
+ }
+ if (init_map & SETTINGS_PROC_FILE) {
+ printk( DRIVER_NAME " removing " GPIO_PROC_PORTADIR_FILENAME " & Co\n" );
+ remove_proc_entry( GPIO_PROC_PORTADIR_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTBDIR_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTCDIR_FILENAME, NULL);
+ remove_proc_entry( GPIO_PROC_PORTDDIR_FILENAME, NULL);
+ }
+ 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);
+}
+/* /dev functionnalities supported: */
static struct file_operations gpio_fops = {
- .owner = THIS_MODULE,
+ .owner = THIS_MODULE,
.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,
+ .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,
};
-//
-// Module's initialization function
-//
+/* Module's initialization */
static int __init armadeus_gpio_init(void)
{
- static int result, i;
+ static int result, i;
+
+ printk("Initializing Armadeus GPIOs driver\n");
+ printk(" PortA Parameters (%i): ", portA_init_nb);
+ for (i = 0; i < NB_CONFIG_REGS; i++) { printk(" 0x%x", portA_init[i]); } printk("\n");
+ printk(" PortB Parameters (%i): ", portB_init_nb);
+ for (i = 0; i < NB_CONFIG_REGS; i++ ) { printk(" 0x%x", portB_init[i]); } printk("\n");
+ 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;
- printk("Initializing Armadeus GPIOs driver\n");
- printk(" PortA Parameters (%i): ", portA_init_nb); for( i=0; i< NB_CONFIG_REGS; i++ ) { printk(" 0x%x", portA_init[i]); } printk("\n");
- printk(" PortB Parameters (%i): ", portB_init_nb); for( i=0; i< NB_CONFIG_REGS; i++ ) { printk(" 0x%x", portB_init[i]); } printk("\n");
- 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 */
+ initialize_all_ports();
- // Configure HW ports/GPIOs with default values or given parameters
- initializePorts();
+ /* 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 */
- /* 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 */
-
/* Creates /proc entries */
- if( (result = create_proc_entries()) ) {
- armadeus_gpio_cleanup();
- return( result );
+ if ((result = create_proc_entries())) {
+ remove_proc_entries();
+ return result;
}
- // Initialise GPIO port access semaphore
- sema_init(&gpio_sema, 1);
+ /* Initialise GPIO port access semaphore */
+ sema_init(&gpio_sema, 1);
- // Set GPIOs to initial state
- // iMX and parameters will do it
+ /* Set GPIOs to initial state: iMX and parameters will do it */
- printk( DRIVER_NAME " " DRIVER_VERSION " successfully loaded !\n");
-
- return(0);
+ printk( DRIVER_NAME " " DRIVER_VERSION " successfully loaded !\n");
+ return 0;
}
-//
-// Module's cleanup function
-//
+/* Module's cleanup */
static void __exit armadeus_gpio_cleanup(void)
{
- printk("Cleanup:\n");
-
/* TBDJUJU free config[i].entry->data first ?? */
+ remove_proc_entries();
- // Remove /proc entries
- if( init_map & GPIO_PROC_FILE )
- {
- printk( DRIVER_NAME " removing " GPIO_PROC_PORTA_FILENAME " & Co\n" );
- remove_proc_entry( GPIO_PROC_PORTA_FILENAME, NULL);
- remove_proc_entry( GPIO_PROC_PORTB_FILENAME, NULL);
- remove_proc_entry( GPIO_PROC_PORTC_FILENAME, NULL);
- remove_proc_entry( GPIO_PROC_PORTD_FILENAME, NULL);
- }
- if( init_map & SETTINGS_PROC_FILE )
- {
- printk( DRIVER_NAME " removing " GPIO_PROC_PORTADIR_FILENAME " & Co\n" );
- remove_proc_entry( GPIO_PROC_PORTADIR_FILENAME, NULL);
- remove_proc_entry( GPIO_PROC_PORTBDIR_FILENAME, NULL);
- remove_proc_entry( GPIO_PROC_PORTCDIR_FILENAME, NULL);
- remove_proc_entry( GPIO_PROC_PORTDDIR_FILENAME, NULL);
- }
- 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");
+ /* De-register from /dev interface */
+ unregister_chrdev(gpio_major, DRIVER_NAME);
}
-//------------------------------------------------
-//
-// API TBDJUJU To be removed......
-//
-
+/*
+ * API To be removed ???
+ */
void gpioWriteOnPort( unsigned int aPort, unsigned int aValue )
{
if( aPort >= NB_PORTS ) { aPort = NB_PORTS - 1; printk(DRIVER_NAME "port unknown !\n"); return; }
Modified: trunk/target/linux/modules/gpio/ppdevemu.c
===================================================================
--- trunk/target/linux/modules/gpio/ppdevemu.c 2009-03-10 12:50:55 UTC (rev 1138)
+++ trunk/target/linux/modules/gpio/ppdevemu.c 2009-03-10 14:32:12 UTC (rev 1139)
@@ -1,5 +1,9 @@
/*
- **********************************************************************
+ * Armadeus Parallel port (ppdev) emulator
+ *
+ * Copyright (C) 2006-2009 Julien Boibessot <jul...@ar...>
+ * Armadeus Project / Armadeus 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,31 +17,33 @@
* 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.
- **********************************************************************
+ *
*/
-/*#define GPIO_PROC_FILE 1
-#define LED_PROC_FILE 2
-#define SETTINGS_PROC_FILE 4
-#define TEMP_PROC_FILE 8
-#define VOLT_PROC_FILE 16*/
-
-//#include "common.h"
-#include "ppdevemu.h"
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
-#include <asm/arch/imx-regs.h>
-#else
-#include <mach/imx-regs.h>
-#endif
#include <linux/moduleparam.h>
+/* Pretend we're PPDEV for IOCTL */
+#include <linux/ppdev.h>
+
extern void gpioWriteOnPort( unsigned int, unsigned int );
extern unsigned int gpioReadFromPort( unsigned int );
extern void gpioSetPortDir( unsigned int, unsigned int );
extern unsigned int gpioGetPortDir( unsigned int );
+#define DRIVER_VERSION "v0.1"
+#define PPDEV_DEVICE_NAME "Armadeus_ppdev"
+/* by default, we use dynamic allocation of major numbers */
+#define PPDEV_MAJOR 0
+#define PPDEV_MAX_MAJOR 254
+#define PPDEV_MINOR 0
+#define PPDEV_MAX_MINOR 4
+
#define PORT_A 0
#define PORT_B 1
#define PORT_C 2
@@ -61,328 +67,236 @@
static unsigned int gPortCIndex = PORT_C;
static unsigned int gPortDIndex = PORT_D;*/
-static unsigned char port_mode = 8; // 8bits mode by default
+static unsigned char port_mode = 8; /* 8bits mode by default */
module_param( port_mode, byte, 0 );
+MODULE_PARM_DESC(port_mode, "Choose between 8 or 4 bits mode");
+
void __exit armadeus_ppdev_cleanup(void);
-//------------------------------------------------
-//
-// Low level functions
-//
-static void initializePorts( void )
+/*
+ * Low level functions
+ */
+static void initialize_port( void )
{
- // If not already done by core module
- 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;
+ /* If not already done by core module */
+ 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;
}
-//------------------------------------------------
-//
-// Handles write() done on /dev/ppdevxx
-//
+/* Handles write() done on /dev/ppdevxx */
/*static ssize_t armadeus_ppdev_write(struct file *file, const char *data, size_t count, loff_t *ppos)
{
}*/
-//
-// Handles read() done on /dev/ppdevxx
-//
+/* Handles read() done on /dev/ppdevxx */
/*static ssize_t armadeus_ppdev_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
}*/
-//------------------------------------------------
-//
-// Handles open() system call done on /dev/...
-//
+/* Handles open() system call done on /dev/... */
static int armadeus_ppdev_open(struct inode *inode, struct file *file)
{
- unsigned m = MINOR(inode->i_rdev);
- if( m != PPDEV_MINOR /*MINOR_BYTE && m != MINOR_FULL && m != MINOR_LED*/ )
- {
- printk("Not the right parport minor\n");
- return -EINVAL;
- }
+ unsigned m = MINOR(inode->i_rdev);
+ if (m != PPDEV_MINOR) {
+ printk("Not the right parport minor\n");
+ return -EINVAL;
+ }
- printk("Opening /dev/ppdev%d file\n", m);
- return 0;
+ pr_debug("Opening /dev/ppdev%d file\n", m);
+ return 0;
}
-//------------------------------------------------
-//
-// Handles close() system call done on /dev/...
-//
+/* Handles close() system call done on /dev/... */
static int armadeus_ppdev_release(struct inode *inode, struct file *file)
{
- printk("Closing access to /dev/ppdev\n");
- return 0;
+ pr_debug("Closing access to /dev/ppdev\n");
+ return 0;
}
-//------------------------------------------------
-
-// PROC file
-static int procfile_ppdev_read( char *buffer, __attribute__ ((unused)) char **start, off_t offset, int buffer_length, int *eof, __attribute__ ((unused)) void* data)
-{
- int len; /* The number of bytes actually used */
-
- // 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 < /*MIN_SIZE_OF_PROC*/32) )
- {
- return 0;
- }
-
-/* if (down_interruptible(&fpga_sema))
- return -ERESTARTSYS; */
-
- // Get the status of the fpga TBDNICO
-
- // Put status to given buffer
- len = sprintf(buffer, "Nothing to say yet :-) !\n");
-
- //*start = buffer;
- *eof = 1;
-/* up(&fpga_sema); */
-
- // Return the length
- return len;
-}
-
-
-static int procfile_ppdev_write( __attribute__ ((unused)) struct file *file, const char *buf, unsigned long count, void *data)
-{
- int len = 0;
-
- printk( "Not supported !\n" );
-
- return len;
-}
-
-
-//------------------------------------------------
-// Handling of some PPDEV IOCTL calls
-//
+/* Handling of some PPDEV IOCTL calls */
int armadeus_ppdev_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg )
{
- int err = 0; int ret = 0;
- int value=0;
- unsigned int minor;
- unsigned int lShadow = 0;
- unsigned int PP_DDIR_MASK=0;
+ int err = 0; int ret = 0;
+ int value=0;
+ unsigned int minor;
+ unsigned int lShadow = 0;
+ unsigned int PP_DDIR_MASK=0;
- //printk(" ## 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) != PP_IOCTL) return -ENOTTY;
+ pr_debug(" ## IOCTL received: (0x%x) ##\n", cmd);
- // 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));
+ /* Extract the type and number bitfields, and don't decode wrong cmds:
+ return ENOTTY (inappropriate ioctl) before access_ok() */
+ if (_IOC_TYPE(cmd) != PP_IOCTL)
+ return -ENOTTY;
- if (err) return -EFAULT;
+ /* 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;
- if (down_interruptible(&ppdev_sema))
- return -ERESTARTSYS;
+ if (down_interruptible(&ppdev_sema))
+ return -ERESTARTSYS;
- minor = MINOR(inode->i_rdev);
- if( minor > PPDEV_MAX_MINOR ) {
- printk("Minor outside range: %d !\n", minor);
- return -EFAULT;
- }
-
- switch(cmd)
- {
- case PPCLAIM:
- case PPRELEASE:
- break;
- case PPFCONTROL: // Normally not used in 4bits mode because in this case control signals are generated with data port
- ret = __get_user(value, (unsigned char *)arg);
- // Write ctrl infos on assigned ctrl ppdevlines how ???
- printk("/FROB 0x%x/ ", value);
- // Get value from port and clear bits we will set
- lShadow = gpioReadFromPort( PORT_D );
- // Control lines are on PortD[14,13,12]
- lShadow &= 0xFFFF8FFF;
- //Control are written on iMX LCD Port control in GPIO mode, ie PortD[14,13,12]
- lShadow |= ((value & 0x0F) << 12);
- // Put it on port
- gpioWriteOnPort( PORT_D, lShadow );
- printk(" 0x%x /", lShadow);
- break;
+ minor = MINOR(inode->i_rdev);
+ if( minor > PPDEV_MAX_MINOR ) {
+ printk("Minor outside range: %d !\n", minor);
+ return -EFAULT;
+ }
- // IOCTL used to write on data register of the simulated parallel port
- // We will ask LCD4LINUX to use 4 bits mode for controlling the LCD and to use the 4 remaining data line as control lines
- // So, 4 lowest bit received as argument are data and 4 highest bits are control
- // !! Minor number is ignored for all PPDEV IOCTLs !!
- case PPWDATA:
- ret = __get_user(value, (unsigned char *)arg);
-// printk("/WD 0x%x ", value);
- if (ret==0) {
- // Get value from port and clear bits we will set
- lShadow = gpioReadFromPort( PORT_D );
- if( port_mode == 4 ) {
- lShadow &= 0xFF000FFF; //0xFFF00FFF;
- //Control (4 highest bits) are written on iMX LCD Port control in GPIO mode, ie PortD[14,13,12]
- lShadow |= ((value & 0x70) << (12-4));
- //Data (4 lowest bits) are writtten on iMX LCD port data in GPIO mode, ie PortD[18-15]
- lShadow |= ((value & 0x0F) << (15+4));
- } else {
- lShadow &= 0xFF807FFF;
- lShadow |= ((value & 0xFF) << 15);
- }
- gpioWriteOnPort( PORT_D, lShadow );
-// printk(" 0x%x /", lShadow);
- }
- break;
+ switch (cmd)
+ {
+ case PPCLAIM:
+ case PPRELEASE:
+ break;
- case PPRDATA:
- if( port_mode == 4 ) {
- // Data (4 lowest bits) are read from iMX LCD port data in GPIO mode, ie PortD[18-15]
- value = (gpioReadFromPort( PORT_D ) >> (15+4)) & 0x0F;
- } else {
- value = (gpioReadFromPort( PORT_D ) >> 15) & 0xFF;
- }
- //
- ret = __put_user(value, (unsigned char *)arg);
- printk("/RD 0x%x/ ", value);
- break;
+ case PPFCONTROL: // Normally not used in 4bits mode because in this case control signals are generated with data port
+ ret = __get_user(value, (unsigned char *)arg);
+ /* Write ctrl infos on assigned ctrl ppdevlines how ??? */
+ printk("/FROB 0x%x/ ", value);
+ /* Get value from port and clear bits we will set */
+ lShadow = gpioReadFromPort( PORT_D );
+ /* Control lines are on PortD[14,13,12] */
+ lShadow &= 0xFFFF8FFF;
+ /* Control are written on iMX LCD Port control in GPIO mode, ie PortD[14,13,12] */
+ lShadow |= ((value & 0x0F) << 12);
+ /* Put it on port */
+ gpioWriteOnPort( PORT_D, lShadow );
+ printk(" 0x%x /", lShadow);
+ break;
- case PPDATADIR:
- ret = __get_user(value, (unsigned char *)arg);
- printk("/DIR 0x%x/ ", value);
-
- if( port_mode == 4 )
- PP_DDIR_MASK = 0xFF807FFF; // 1111 1111 1111 1000 0111 1111 1111 1111 ??
- else
- PP_DDIR_MASK = 0xFF807FFF; // 1111 1111 1000 0000 0111 1111 1111 1111
-
- /* linux/ppdev.h define PPDATADIR as "Data line direction: non-zero for input mode."
- For ppdevs, the logic is reversed - bit=1 == output
- This is _not_ "generic" at all, but very much hard-wired towards being able to use an HD44780 LCD on the GPIO pins
- (in 4-bit mode) and being able to do so using generic ppdev instructions
- So, GPIO4-GPIO7 (=ctrl signals) will _always_ be set to output for this call, only GPIO0-GPIO3 (=datalines) are changed */
- if( ret == 0 )
- {
- lShadow = gpioGetPortDir( PORT_D );
- //only 4 data lines can be set to ouput/input, control lines are always output...
- if( value==0 ) {
- gpioSetPortDir( PORT_D, (lShadow | (!PP_DDIR_MASK)) );
- } else {
- gpioSetPortDir( PORT_D, (lShadow & PP_DDIR_MASK) );
- }
- } else {
- printk(PPDEV_DEVICE_NAME ": ret=%x\n", ret);
- }
- break;
+ /* IOCTL used to write on data register of the simulated
+ parallel port. We will ask LCD4LINUX to use 4 bits mode
+ for controlling the LCD and to use the 4 remaining data
+ line as control lines.
+ So, 4 lowest bit received as argument are data and
+ 4 highest bits are control
+ !! Minor number is ignored for all PPDEV IOCTLs !! */
+ case PPWDATA:
+ ret = __get_user(value, (unsigned char *)arg);
+ /*printk("/WD 0x%x ", value);*/
+ if (ret !=0 )
+ break;
- default:
- return -ENOTTY;
- break;
- }
+ /* Get value from port and clear bits we will set */
+ lShadow = gpioReadFromPort( PORT_D );
+ if (port_mode == 4) {
+ lShadow &= 0xFF000FFF; //0xFFF00FFF;
+ /* Control (4 highest bits) are written on iMX LCD
+ Port control in GPIO mode, ie PortD[14,13,12] */
+ lShadow |= ((value & 0x70) << (12-4));
+ /* Data (4 lowest bits) are written on iMX LCD port
+ data in GPIO mode, ie PortD[18-15] */
+ lShadow |= ((value & 0x0F) << (15+4));
+ } else {
+ lShadow &= 0xFF807FFF;
+ lShadow |= ((value & 0xFF) << 15);
+ }
+ gpioWriteOnPort( PORT_D, lShadow );
+ /*printk(" 0x%x /", lShadow); */
+ break;
- up(&ppdev_sema);
+ case PPRDATA:
+ if (port_mode == 4) {
+ /* Data (4 lowest bits) are read from iMX LCD port data
+ in GPIO mode, ie PortD[18-15] */
+ value = (gpioReadFromPort( PORT_D ) >> (15+4)) & 0x0F;
+ } else {
+ value = (gpioReadFromPort( PORT_D ) >> 15) & 0xFF;
+ }
+
+ ret = __put_user(value, (unsigned char *)arg);
+ printk("/RD 0x%x/ ", value);
+ break;
- return ret;
-}
+ case PPDATADIR:
+ ret = __get_user(value, (unsigned char *)arg);
+ printk("/DIR 0x%x/ ", value);
+
+ if (port_mode == 4)
+ PP_DDIR_MASK = 0xFF807FFF; /* 1111 1111 1111 1000 0111 1111 1111 1111 ?? */
+ else
+ PP_DDIR_MASK = 0xFF807FFF; /* 1111 1111 1000 0000 0111 1111 1111 1111 */
+
+ /* linux/ppdev.h define PPDATADIR as "Data line direction: non-zero for input mode."
+ For ppdevs, the logic is reversed - bit=1 == output
+ This is _not_ "generic" at all, but very much hard-wired towards being able to use an HD44780 LCD on the GPIO pins
+ (in 4-bit mode) and being able to do so using generic ppdev instructions
+ So, GPIO4-GPIO7 (=ctrl signals) will _always_ be set to output for this call, only GPIO0-GPIO3 (=datalines) are changed */
+ if (ret == 0) {
+ lShadow = gpioGetPortDir( PORT_D );
+ /* only 4 data lines can be set to ouput/input, control lines are always output...*/
+ if (value==0) {
+ gpioSetPortDir( PORT_D, (lShadow | (!PP_DDIR_MASK)) );
+ } else {
+ gpioSetPortDir( PORT_D, (lShadow & PP_DDIR_MASK) );
+ }
+ } else {
+ printk(PPDEV_DEVICE_NAME ": ret=%x\n", ret);
+ }
+ break;
-//
-// Create /proc entries for direct access (with echo/cat) to GPIOs config
-//
-static int createProcEntries( void )
-{
- static struct proc_dir_entry* pPPDEVProcFile;
- //
- printk("Creating /proc entries: ");
- // Create main directory
- proc_mkdir(PPDEV_PROC_DIRNAME, NULL);
- // Create proc file to handle GPIO values
- pPPDEVProcFile = create_proc_entry( PPDEV_PROC_FILENAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, NULL);
+ default:
+ return -ENOTTY;
+ break;
+ }
- if( pPPDEVProcFile == NULL )
- {
- printk(KERN_ERR PPDEV_DEVICE_NAME ": Could not register " PPDEV_PROC_FILENAME ". Terminating\n");
- armadeus_ppdev_cleanup();
- return -ENOMEM;
- }
- else
- {
- pPPDEVProcFile->read_proc = procfile_ppdev_read;
- pPPDEVProcFile->write_proc = procfile_ppdev_write;
- //init_map |= GPIO_PROC_FILE;
- }
-
- printk("OK!\n");
- return(0);
+ up(&ppdev_sema);
+
+ return ret;
}
static struct file_operations ppdev_fops = {
- .owner = THIS_MODULE,
-// .write = armadeus_ppdev_write,
-// .read = armadeus_ppdev_read,
- .open = armadeus_ppdev_open,
- .release = armadeus_ppdev_release,
- .ioctl = armadeus_ppdev_ioctl,
+ .owner = THIS_MODULE,
+ /*.write = armadeus_ppdev_write,
+ .read = armadeus_ppdev_read,*/
+ .open = armadeus_ppdev_open,
+ .release = armadeus_ppdev_release,
+ .ioctl = armadeus_ppdev_ioctl,
};
-//
-// Module's initialization function
-//
+
int __init armadeus_ppdev_init(void)
{
- static int result;
+ static int result;
- printk("Initializing Armadeus Parallel Port emulation driver\n");
- printk(" Port mode: %d bits\n", port_mode );
- init_map = 0;
-
- // Configure HW ports/GPIOs with default values or given parameters
- initializePorts();
-
- // Register the driver by getting a major number
- result = register_chrdev(ppdev_major, PPDEV_DEVICE_NAME, &ppdev_fops);
- if (result < 0) {
- printk(KERN_WARNING PPDEV_DEVICE_NAME ": can't get major %d\n", ppdev_major);
- return result;
- }
- // Dynamic Major allocation
- if( ppdev_major == 0 )
- ppdev_major = result;
+ printk("Initializing Armadeus Parallel Port emulation driver\n");
+ printk(" Port mode: %d bits\n", port_mode );
+ init_map = 0;
- // Creating /proc entries
- result = createProcEntries();
- if( result < 0 ) return( result );
-
- // Initialise GPIO port access semaphore
- sema_init(&ppdev_sema, 1);
+ /* Configure HW ports/GPIOs with default values or given parameters */
+ initialize_port();
- printk("Armadeus Parallel Port emulation driver " DRIVER_VERSION " successfully loaded !\n");
+ /* Register the driver by getting a major number */
+ result = register_chrdev(ppdev_major, PPDEV_DEVICE_NAME, &ppdev_fops);
+ if (result < 0) {
+ printk(KERN_WARNING PPDEV_DEVICE_NAME ": can't get major %d\n", ppdev_major);
+ return result;
+ }
+ /* Dynamic Major allocation */
+ if( ppdev_major == 0 )
+ ppdev_major = result;
- return(0);
+ /* Initialise GPIO port access semaphore */
+ sema_init(&ppdev_sema, 1);
+
+ printk(DRIVER_VERSION " successfully loaded !\n");
+
+ return(0);
}
-//
-// Module's cleanup function
-//
void __exit armadeus_ppdev_cleanup(void)
{
- printk("PPDEV cleanup: ");
- remove_proc_entry( PPDEV_PROC_FILENAME, NULL );
- remove_proc_entry( PPDEV_PROC_DIRNAME, NULL);
- printk("2 ");
- unregister_chrdev(ppdev_major, PPDEV_DEVICE_NAME);
-
- printk("Ok !\n ");
+ unregister_chrdev(ppdev_major, PPDEV_DEVICE_NAME);
}
-//------------------------------------------------
module_init(armadeus_ppdev_init);
module_exit(armadeus_ppdev_cleanup);
Deleted: trunk/target/linux/modules/gpio/ppdevemu.h
===================================================================
--- trunk/target/linux/modules/gpio/ppdevemu.h 2009-03-10 12:50:55 UTC (rev 1138)
+++ trunk/target/linux/modules/gpio/ppdevemu.h 2009-03-10 14:32:12 UTC (rev 1139)
@@ -1,80 +0,0 @@
-/*
- **********************************************************************
- * 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 __PPDEV_EMU_H__
-#define __PPDEV_EMU_H__
-
-#include <linux/version.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>
-#include <linux/pci.h>
-
-#define PPDEV_PROC_DIRNAME "driver/ppdev"
-#define PPDEV_PROC_FILENAME PPDEV_PROC_DIRNAME "/infos"
-
-/*#define LED_PROC_FILENAME "driver/armadeus_error_led"
-#define SETTINGS_PROC_FILENAME "driver/portBdir"
-#define TEMPERATURE_PROC_FILENAME "driver/soekris_temp"
-#define VOLTAGE_PROC_FILENAME "driver/soekris_voltage"*/
-#define DRIVER_VERSION "v0.0"
-//#define VERSION "soekris"
-
-/* by default, we use dynamic allocation of major numbers */
-#define PPDEV_MAJOR 0
-#define PPDEV_MAX_MAJOR 254
-
-// /* minor numbers used*/
-// #define MINOR_BYTE 0 /* access to GPIO0-GPIO7 */
-// #define MINOR_FULL 1 /* access to GPIO0-GPIOxx (driver dependant) */
-// #define MINOR_LED 254 /* access to the error LED */
-// #define GPIO_MAX_MINOR 4
-#define PPDEV_MINOR 0
-#define PPDEV_MAX_MINOR 4
-
-// /* Read/write bitmask that determines input/output pins (1 means output, 0 input) */
-// #define GPIORDDIRECTION _IOR(PP_IOCTL, 0xF0, int)
-// #define GPIOWRDIRECTION _IOW(PP_IOCTL, 0xF1, int)
-//
-// /* Read/write data */
-// #define GPIORDDATA _IOR(PP_IOCTL, 0xF2, int)
-// #define GPIOWRDATA _IOW(PP_IOCTL, 0xF3, int)
-
-// #define MAX_NUMBER_OF_PINS 32
-// #define TEMPERATURE_BUFFER_SIZE 256
-// #define VOLTAGE_BUFFER_SIZE 512
-
-#define PPDEV_DEVICE_NAME "Armadeus_ppdev"
-
-// Pretend we're PPDEV for IOCTL
-#include <linux/ppdev.h>
-
-
-#endif // __PPDEV_EMU_H__
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|