[Armadeus-commitlog] SF.net SVN: armadeus:[1213] trunk/target/linux/modules/pwm/pwm.c
Brought to you by:
sszy
|
From: <ar...@us...> - 2009-04-10 21:13:50
|
Revision: 1213
http://armadeus.svn.sourceforge.net/armadeus/?rev=1213&view=rev
Author: artemys
Date: 2009-04-10 21:13:39 +0000 (Fri, 10 Apr 2009)
Log Message:
-----------
[LINUX] cleanup PWM driver before adding APF27 support (good luck nico ;-))
Modified Paths:
--------------
trunk/target/linux/modules/pwm/pwm.c
Modified: trunk/target/linux/modules/pwm/pwm.c
===================================================================
--- trunk/target/linux/modules/pwm/pwm.c 2009-04-10 12:08:02 UTC (rev 1212)
+++ trunk/target/linux/modules/pwm/pwm.c 2009-04-10 21:13:39 UTC (rev 1213)
@@ -1,5 +1,4 @@
/*
- *
* Driver for the i.MX PWM driver
*
* This driver is part of the Armadeus Project and is the merge of a lot of ideas
@@ -21,7 +20,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- *
*/
//#define DEBUG 1
@@ -51,23 +49,23 @@
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/pm.h>
-// For /sys
+/* For /sys */
#include <linux/sysdev.h>
-// For struct class
+/* For struct class */
#include <linux/device.h>
-// For circular buffer
+/* For circular buffer */
#include <linux/circ_buf.h>
+
#include <mach/hardware.h>
+#include <linux/platform_device.h>
+#include "pwm.h"
+
// additional defines
#define PWMC_PRESCALER_MASK 0x00007F00
#define PWMC_REPEAT_MASK 0x0000000C
#define PWMC_CLKSEL_MASK 0x00000003
-//
-#include <linux/platform_device.h>
-#include "pwm.h"
-
#define PWM_TEST
#define DRIVER_NAME "imx-pwm"
@@ -81,10 +79,10 @@
struct pwm_device {
- u32 reg;
- int active;
- unsigned duty;
- /*const*/ struct pwm_table *entry;
+ u32 reg;
+ int active;
+ unsigned duty;
+ /*const*/ struct pwm_table *entry;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
struct class_device class_dev;
#else
@@ -97,10 +95,9 @@
#define to_pwm_device(d) container_of(d, struct pwm_device, class_dev)
-// Global variables
+/* Global variables */
int gPwmMode;
-//char *gpWriteBuf;
-int g4bytes; // count 4 bytes write occurence to FIFO
+int g4bytes; /* count 4 bytes write occurence to FIFO */
u8 *gpWriteBufPtr;
u16 *gpWriteBufPtr16;
int gDataLen = PWM_DATA_8BIT;
@@ -113,25 +110,25 @@
wait_queue_head_t exit_wait;
struct fasync_struct *ts_fasync;
-int gMajor = 0; /* TODO dynamic major for now */
+int gMajor = 0; /* TODO dynamic major for now */
typedef struct timer_list timer_blk_t;
typedef struct timerStruct
{
- timer_blk_t *timer_blk_ptr;
- int period;
- void (*timer_func)(unsigned long);
- int stop_flag;
+ timer_blk_t *timer_blk_ptr;
+ int period;
+ void (*timer_func)(unsigned long);
+ int stop_flag;
} PWM_Timer_t;
static PWM_Timer_t pwmTimer;
static timer_blk_t timer_blk;
struct pwm_table {
- long period; /* in us */
- unsigned max_period_val;
- unsigned prescaler;
+ long period; /* in us */
+ unsigned max_period_val;
+ unsigned prescaler;
};
struct pwm_table pwmdata;
@@ -139,66 +136,66 @@
* Ready to use calculations
*/
static const struct pwm_table pwm_table[]={
- {
- .period=1, /* 1 us */
- .max_period_val = 13,
- .prescaler=1,
- },
- {
- .period=5, /* 5 us */
- .max_period_val = 65,
- .prescaler=1,
- },
- {
- .period=10, /* 10 us */
- .max_period_val = 130,
- .prescaler=1,
- },
- {
- .period=20, /* 20 us */
- .max_period_val = 260,
- .prescaler=1,
- },
- {
- .period=50, /* 50 us */
- .max_period_val = 650,
- .prescaler=1,
- },
- {
- .period=100, /* 100 us */
- .max_period_val = 650,
- .prescaler=2,
- },
- {
- .period=500, /* 500 us */
- .max_period_val = 929,
- .prescaler=7,
- },
- {
- .period=1000, /* 1ms */
- .max_period_val = 1000,
- .prescaler=13,
- },
- {
- .period=2000, /* 2ms */
- .max_period_val = 1000,
- .prescaler=26,
- },
- {
- .period=3000, /* 3ms */
- .max_period_val = 1000,
- .prescaler=39,
- },
- {
- .period=4000, /* 4ms */
- .max_period_val = 1020,
- .prescaler=51,
- },
- {
- .period=5000, /* 5ms */
- .max_period_val = 1016,
- .prescaler=64,
- }
+ {
+ .period=1, /* 1 us */
+ .max_period_val = 13,
+ .prescaler=1,
+ },
+ {
+ .period=5, /* 5 us */
+ .max_period_val = 65,
+ .prescaler=1,
+ },
+ {
+ .period=10, /* 10 us */
+ .max_period_val = 130,
+ .prescaler=1,
+ },
+ {
+ .period=20, /* 20 us */
+ .max_period_val = 260,
+ .prescaler=1,
+ },
+ {
+ .period=50, /* 50 us */
+ .max_period_val = 650,
+ .prescaler=1,
+ },
+ {
+ .period=100, /* 100 us */
+ .max_period_val = 650,
+ .prescaler=2,
+ },
+ {
+ .period=500, /* 500 us */
+ .max_period_val = 929,
+ .prescaler=7,
+ },
+ {
+ .period=1000, /* 1ms */
+ .max_period_val = 1000,
+ .prescaler=13,
+ },
+ {
+ .period=2000, /* 2ms */
+ .max_period_val = 1000,
+ .prescaler=26,
+ },
+ {
+ .period=3000, /* 3ms */
+ .max_period_val = 1000,
+ .prescaler=39,
+ },
+ {
+ .period=4000, /* 4ms */
+ .max_period_val = 1020,
+ .prescaler=51,
+ },
+ {
+ .period=5000, /* 5ms */
+ .max_period_val = 1016,
+ .prescaler=64,
+ }
};
/****************************************************************
@@ -206,39 +203,39 @@
***************************************************************/
struct sound_circ_buf {
- char* buf;
- int write; // == head
- int read; // == tail
- int size;
+ char* buf;
+ int write; /* == head */
+ int read; /* == tail */
+ int size;
};
static inline u8 get_byte_from_circbuf( struct sound_circ_buf* abuffer )
{
- u8 b = abuffer->buf[ abuffer->read ];
- abuffer->read = (abuffer->read + 1) & (abuffer->size - 1);
- return b;
+ u8 b = abuffer->buf[ abuffer->read ];
+ abuffer->read = (abuffer->read + 1) & (abuffer->size - 1);
+ return b;
}
static inline u16 get_word_from_circbuf( struct sound_circ_buf* abuffer )
{
- u16 w = *((u16*)(&(abuffer->buf[ abuffer->read ])));
- abuffer->read = (abuffer->read + 2) & (abuffer->size - 1);
- return w;
+ u16 w = *((u16*)(&(abuffer->buf[ abuffer->read ])));
+ abuffer->read = (abuffer->read + 2) & (abuffer->size - 1);
+ return w;
}
static inline void put_byte_to_circbuf( struct sound_circ_buf* abuffer, unsigned char abyte )
{
- abuffer->buf[ abuffer->write ] = abyte;
- abuffer->write = (abuffer->write + 1) & (abuffer->size - 1);
+ abuffer->buf[ abuffer->write ] = abyte;
+ abuffer->write = (abuffer->write + 1) & (abuffer->size - 1);
}
static inline void increase_circbuf( struct sound_circ_buf* abuffer, int count )
{
- abuffer->write = (abuffer->write + count) & (abuffer->size - 1);
- pr_debug("Added %d bytes to buffer, now write is in pos %d\n", count, abuffer->write);
+ abuffer->write = (abuffer->write + count) & (abuffer->size - 1);
+ pr_debug("Added %d bytes to buffer, now write is in pos %d\n", count, abuffer->write);
}
-#define MAX_SOUND_BUFFER_SIZE (16*1024) // !! Should be a power of 2 !!
+#define MAX_SOUND_BUFFER_SIZE (16*1024) /* !! Should be a power of 2 !! */
static struct sound_circ_buf gPWM_Circ_Buf;
/****************************************************************
@@ -254,111 +251,66 @@
*/
static void setup_pwm_unit(struct pwm_device *ppd)
{
- if (ppd->entry == NULL)
- return; /* do nothing, not fully configured yet */
+ if (ppd->entry == NULL)
+ return; /* do nothing, not fully configured yet */
- if (ppd->active)
- {
- // Activate PWM
- PWMC |= PWMC_EN;
-
- // Setup prescaler
- pr_debug("Updating PWM registers\n");
- PWMC = (PWMC & ~PWMC_PRESCALER_MASK) | PWMC_PRESCALER(ppd->entry->prescaler) /*| PWMC_REPEAT(3)*/;
-
- // Setup period
- PWMP = PWMP_PERIOD(ppd->entry->period);
-
- // Setup duty
- PWMS = PWMS_SAMPLE( (u32) ((ppd->entry->period * ppd->duty) / 1000) );
-/* unsigned duty;
-
- if (ppd->duty == MAX_DUTY)
- duty=ppd->entry->max_period_val-1; // FIXME: Solve with bit 10 in this register
- else
- duty=((ppd->entry->max_period_val-1)*ppd->duty)/MAX_DUTY;
-*/
-
- }
- else
- {
- // De-activate
- PWMC &= ~PWMC_EN;
- }
+ if (ppd->active) {
+ /* Activate PWM */
+ PWMC |= PWMC_EN;
+ /* Setup prescaler */
+ pr_debug("Updating PWM registers\n");
+ PWMC = (PWMC & ~PWMC_PRESCALER_MASK) | PWMC_PRESCALER(ppd->entry->prescaler) /*| PWMC_REPEAT(3)*/;
+ /* Setup period */
+ PWMP = PWMP_PERIOD(ppd->entry->period);
+ /* Setup duty cycle */
+ PWMS = PWMS_SAMPLE( (u32) ((ppd->entry->period * ppd->duty) / 1000) );
+ } else {
+ /* De-activate */
+ PWMC &= ~PWMC_EN;
+ }
}
-/******************************************************************************
- * Function Name: checkDevice
- *
- * Input: inode :
- * Value Returned: int : Return status.If no error, return 0.
- *
- * Description: verify if the inode is a correct inode
- *
- * Modification History:
- * 10 DEC,2001,
- *****************************************************************************/
-// static int checkDevice(struct inode *pInode)
-// {
-// int minor;
-// kdev_t dev = pInode->i_rdev;
-//
-// if( MAJOR(dev) != gMajor)
-// {
-// PK("<1>checkDevice bad major = %d\n",MAJOR(dev) );
-// return -1;
-// }
-// minor = MINOR(dev);
-//
-// if ( minor < MAX_ID )
-// return minor;
-// else
-// {
-// PK("<1>checkDevice bad minor = %d\n",minor );
-// return -1;
-// }
-// }
-
/* timer */
-int CreateTimer(PWM_Timer_t *timer)
+static int create_timer(PWM_Timer_t *timer)
{
- init_timer(timer->timer_blk_ptr);
- timer->timer_blk_ptr->function = timer->timer_func;
+ init_timer(timer->timer_blk_ptr);
+ timer->timer_blk_ptr->function = timer->timer_func;
- return(0);
+ return(0);
}
-int StartTimer(PWM_Timer_t *timer)
+static int start_timer(PWM_Timer_t *timer)
{
- timer->timer_blk_ptr->expires = jiffies + timer->period;
- timer->stop_flag = 0;
+ timer->timer_blk_ptr->expires = jiffies + timer->period;
+ timer->stop_flag = 0;
- add_timer((struct timer_list *)timer->timer_blk_ptr);
+ add_timer((struct timer_list *)timer->timer_blk_ptr);
- return(0);
+ return(0);
}
-int StopTimer(PWM_Timer_t *timer)
+
+static int stop_timer(PWM_Timer_t *timer)
{
- timer->stop_flag = 1;
- del_timer_sync((struct timer_list *)timer->timer_blk_ptr);
+ timer->stop_flag = 1;
+ del_timer_sync((struct timer_list *)timer->timer_blk_ptr);
- return(0);
+ return(0);
}
-static void StopPwm(void)
+static void stop_pwm(void)
{
- PWMC &= ~PWMC_IRQEN; // disable IRQ
- PWMC &= ~PWMC_EN; // disable PWM
+ PWMC &= ~PWMC_IRQEN; /* disable IRQ */
+ PWMC &= ~PWMC_EN; /* disable PWM */
- gSampleValue = 0;
- if(gPwmMode == PWM_TONE_MODE)
- StopTimer(&pwmTimer);
+ gSampleValue = 0;
+ if(gPwmMode == PWM_TONE_MODE)
+ StopTimer(&pwmTimer);
- // Can release file now
- wake_up_interruptible(&exit_wait);
+ /* Can release file now */
+ wake_up_interruptible(&exit_wait);
- PK("<1>data completed.\n");
- PK("<1>PWMC = 0x%8x\n", (u32)PWMC);
+ PK("<1>data completed.\n");
+ PK("<1>PWMC = 0x%8x\n", (u32)PWMC);
}
static void pwmIntFunc( unsigned long unused)
@@ -389,81 +341,50 @@
}
-// static int handle_pm_event(struct pm_dev *dev, pm_request_t rqst, void *data)
-// {
-// switch(rqst)
-// {
-// case PM_SUSPEND:
-// PK("<1> PM suspend event received in PWM device.\n");
-// StopPwm();
-// break;
-//
-// case PM_RESUME:
-// PK("<1> PM resume event received in PWM device.\n");
-// break;
-//
-// default:
-// break;
-// }
-// return 0;
-// }
-
-/******************************************************************************
- *
- *****************************************************************************/
-static int initPWM(void)
+static int init_pwm(void)
{
- // Init Port PA[2] : PWMO
- // Should be done in apf9328.c non ???
- DDIR(0) |= 0x00000002;
- GIUS(0) &= ~0x00000002;
- GPR(0) &= ~0x00000002;
+ /* Init Port PA[2] : PWMO
+ Should be done in apf9328.c non ??? */
+ DDIR(0) |= 0x00000002;
+ GIUS(0) &= ~0x00000002;
+ GPR(0) &= ~0x00000002;
- // Software reset
- PWMC |= PWMC_SWR;
- udelay(10);
- // Activate & de-activate PWM (seems to be necessary after a reset)
- PWMC |= PWMC_EN; PWMC &= ~PWMC_EN;
+ /* Software reset */
+ PWMC |= PWMC_SWR;
+ udelay(10);
+ /* Activate & de-activate PWM (seems to be necessary after a reset) */
+ PWMC |= PWMC_EN; PWMC &= ~PWMC_EN;
- // Enable interrupt
- //PWMC |= PWMC_IRQEN;
+ /* Enable interrupt */
+ //PWMC |= PWMC_IRQEN;
- return 1;
+ return 1;
}
//////////////////////////////////////// /DEV INTERFACE ////////////////////////////////////////////
-/*
- * Called from user space close()
- */
int pwm_release(struct inode * inode, struct file * filp)
{
- // wait unit gWriteCnt == 0
- interruptible_sleep_on(&exit_wait);
-
- if( gPWM_Circ_Buf.buf ) {
- kfree( gPWM_Circ_Buf.buf );
- gPWM_Circ_Buf.buf = 0;
- }
- printk(DRIVER_NAME " released, 4 bytes FIFO usage: %d\n", g4bytes);
- return 0;
+ // wait unit gWriteCnt == 0
+ interruptible_sleep_on(&exit_wait);
+
+ if( gPWM_Circ_Buf.buf ) {
+ kfree( gPWM_Circ_Buf.buf );
+ gPWM_Circ_Buf.buf = 0;
+ }
+ printk(DRIVER_NAME " released, 4 bytes FIFO usage: %d\n", g4bytes);
+ return 0;
}
-/*
- * Called from user space open()
- */
int pwm_open(struct inode * inode, struct file * filp)
{
- // Init PWM hardware
- initPWM();
-
- pr_debug(DRIVER_NAME " opened \n");
- return 0;
+ /* Init PWM hardware */
+ init_pwm();
+
+ pr_debug(DRIVER_NAME " opened \n");
+ return 0;
}
-/*
- *
- */
static int pwm_fasync(int fd, struct file *filp, int mode)
{
PK("<1>in pwm_fasyn ----\n");
@@ -481,238 +402,213 @@
return 0;
}
-/*
- * Called from user space ioctl()
- */
int pwm_ioctl(struct inode * inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
- char *str=NULL;
- int ret = 0;
+ char *str=NULL;
+ int ret = 0;
- pr_debug("pwm_ioctl ----\n");
- switch(cmd)
- {
- // Set PWM Mode (Tone or Playback)
- case PWM_IOC_SMODE:
- {
- gPwmMode = arg;
+ pr_debug("pwm_ioctl ----\n");
+ switch(cmd)
+ {
+ /* Set PWM Mode (Tone or Playback) */
+ case PWM_IOC_SMODE:
+ {
+ gPwmMode = arg;
+
+ if (gPwmMode == PWM_TONE_MODE) {
+ /* create periodic timer when tone mode */
+ pr_debug("PWM Tone Mode.\n");
+ pwmTimer.timer_blk_ptr = &timer_blk;
+ pwmTimer.timer_func = pwmIntFunc;
+ create_timer(&pwmTimer);
+ } else {
+ pr_debug("PWM Play Mode.\n");
+ }
+ }
+ break;
- if (gPwmMode == PWM_TONE_MODE)
- {
- // create periodic timer when tone mode
- pr_debug("PWM Tone Mode.\n");
- pwmTimer.timer_blk_ptr = &timer_blk;
- pwmTimer.timer_func = pwmIntFunc;
- CreateTimer(&pwmTimer);
- }
- else
- {
- pr_debug("PWM Play Mode.\n");
- }
- }
- break;
+ /* Set Playback frequency/ouput rate */
+ case PWM_IOC_SFREQ:
+ {
+ PWMC &= ~PWMC_EN; // Disable PWM
+ PWMC &= ~PWMC_CLKSRC; // Select 16MHz PERCLK1 as CLK source
+ PWMC &= ~PWMC_PRESCALER_MASK; // PRESCALER = 0 => use full 16MHz
+
+ switch(arg)
+ {
+ case PWM_SAMPLING_32KHZ:
+ PWMC &= ~PWMC_REPEAT_MASK; // REPEAT = 0 => divide by 1
+ PWMC &= ~PWMC_CLKSEL_MASK; // CLKSEL = 0 => divide by 2
+ /* 16MHz/256/1/2 = 32768 */
+ str = "32Khz";
+ break;
+ case PWM_SAMPLING_16KHZ:
+ PWMC &= ~PWMC_REPEAT_MASK;
+ PWMC |= PWMC_REPEAT(1); // REPEAT = 01 => divide by 2
+ PWMC &= ~PWMC_CLKSEL_MASK; // CLKSEL = 0 => divide by 2
+ /* 16MHz/256/2/2 = 16384 */
+ str = "16Khz";
+ break;
+
+ case PWM_SAMPLING_8KHZ:
+ default:
+ PWMC &= ~PWMC_REPEAT_MASK;
+ PWMC |= PWMC_REPEAT(2); // REPEAT = 10 => divide by 4
+ PWMC &= ~PWMC_CLKSEL_MASK; // CLKSEL = 0 => divide by 2
+ /* 16MHz/256/4/2 = 8192 */
+ str = "8Khz";
+ break;
+ }
+ pr_debug("Sample rate = %s\n", str);
+ pr_debug("ioctl: PWMC = 0x%8x\n", PWMC);
+ }
+ break;
- // Set Playback frequency/ouput rate
- case PWM_IOC_SFREQ:
- {
- PWMC &= ~PWMC_EN; // Disable PWM
- PWMC &= ~PWMC_CLKSRC; // Select 16MHz PERCLK1 as CLK source
- PWMC &= ~PWMC_PRESCALER_MASK; // PRESCALER = 0 => use full 16MHz
+ /* Set samples length (8 or 16 bits) */
+ case PWM_IOC_SDATALEN:
+ {
+ gDataLen = arg;
+ if (arg == PWM_DATA_8BIT) {
+ PWMP = 0xfe; /* Period, 8bit */
+ str = "8bit";
+ } else { /* if(arg == PWM_DATA_16BIT) */
+ PWMP = 0xfffe; /* Period, 16bit */
+ str = "16bit";
+ }
+ pr_debug("Data Length = %s\n", str);
+ }
+ break;
- switch(arg)
- {
- case PWM_SAMPLING_32KHZ:
- PWMC &= ~PWMC_REPEAT_MASK; // REPEAT = 0 => divide by 1
- PWMC &= ~PWMC_CLKSEL_MASK; // CLKSEL = 0 => divide by 2
- // 16MHz/256/1/2 = 32768
- str = "32Khz";
- break;
- case PWM_SAMPLING_16KHZ:
- PWMC &= ~PWMC_REPEAT_MASK;
- PWMC |= PWMC_REPEAT(1); // REPEAT = 01 => divide by 2
- PWMC &= ~PWMC_CLKSEL_MASK; // CLKSEL = 0 => divide by 2
- // 16MHz/256/2/2 = 16384
- str = "16Khz";
- break;
- case PWM_SAMPLING_8KHZ:
- default:
- PWMC &= ~PWMC_REPEAT_MASK;
- PWMC |= PWMC_REPEAT(2); // REPEAT = 10 => divide by 4
- PWMC &= ~PWMC_CLKSEL_MASK; // CLKSEL = 0 => divide by 2
- // 16MHz/256/4/2 = 8192
- str = "8Khz";
- break;
- }
- pr_debug("Sample rate = %s\n", str);
- pr_debug("ioctl: PWMC = 0x%8x\n", PWMC);
- }
- break;
+ case PWM_IOC_SSAMPLE:
+ gSampleValue = arg;
+ break;
- // Set samples length (8 or 16 bits)
- case PWM_IOC_SDATALEN:
- {
- gDataLen = arg;
- if( arg == PWM_DATA_8BIT )
- {
- PWMP = 0xfe; // Period, 8bit
- str = "8bit";
- }
- else // if(arg == PWM_DATA_16BIT)
- {
- PWMP = 0xfffe; // Period, 16bit
- str = "16bit";
- }
+ case PWM_IOC_SPERIOD:
+ if (gPwmMode == PWM_TONE_MODE)
+ {
+ PK("<1>PWM period = %d\n",(int)arg);
+ pwmTimer.period = arg/12;
+ }
+ break;
- pr_debug("Data Length = %s\n", str);
- }
- break;
+ case PWM_IOC_STOP:
+ stop_pwm();
+ break;
- case PWM_IOC_SSAMPLE:
- gSampleValue = arg;
- break;
+ case PWM_IOC_SWAPDATA:
+ if (arg&PWM_SWAP_HCTRL) { /* Halfword FIFO data swapping */
+ PWMC |= PWMC_HCTR;
+ } else {
+ PWMC &= ~PWMC_HCTR;
+ }
+
+ if (arg & PWM_SWAP_BCTRL) { /* Byte FIFO data swapping */
+ PWMC |= PWMC_BCTR;
+ } else {
+ PWMC &= ~PWMC_BCTR;
+ }
+ break;
- case PWM_IOC_SPERIOD:
- if (gPwmMode == PWM_TONE_MODE)
- {
- PK("<1>PWM period = %d\n",(int)arg);
- pwmTimer.period = arg/12;
- }
- break;
+ default:
+ printk( DRIVER_NAME ": unkown IOCTL\n");
+ break;
+ }
- case PWM_IOC_STOP:
- StopPwm();
- break;
-
- case PWM_IOC_SWAPDATA:
- if (arg&PWM_SWAP_HCTRL) //Halfword FIFO data swapping
- {
- PWMC |= PWMC_HCTR;
- }
- else
- {
- PWMC &= ~PWMC_HCTR;
- }
-
- if (arg&PWM_SWAP_BCTRL) //Byte FIFO data swapping
- {
- PWMC |= PWMC_BCTR;
- }
- else
- {
- PWMC &= ~PWMC_BCTR;
- }
- break;
-
- default:
- printk( DRIVER_NAME ": unkown IOCTL\n");
- break;
- }
-
- return ret;
+ return ret;
}
-/******************************************************************************
- * Called from user space read()
- *
- *****************************************************************************/
ssize_t pwm_read(struct file * filp, char * buf, size_t count, loff_t * l)
{
- int ret = 0;
+ int ret = 0;
- if( PWMC & PWMC_IRQEN )
- ret = 1; // no data
- else
- ret = 0; // processing data
+ if (PWMC & PWMC_IRQEN)
+ ret = 1; /* no data */
+ else
+ ret = 0; /* processing data */
- pr_debug("pwm_read ----\n");
- return ret;
+ pr_debug("pwm_read ----\n");
+
+ return ret;
}
-/******************************************************************************
- * Called from user space write()
- *
- *****************************************************************************/
static ssize_t pwm_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos )
{
- int ret = 0;
- int remaining_space = 0;
+ int ret = 0;
+ int remaining_space = 0;
- pr_debug( "pwm_write ----\n" );
+ pr_debug( "pwm_write ----\n" );
- if( count > MAX_SOUND_BUFFER_SIZE )
- count = MAX_SOUND_BUFFER_SIZE;
- // First time, allocate the double buffer
- if( !gPWM_Circ_Buf.buf ) {
- gPWM_Circ_Buf.buf = kmalloc( count*2, GFP_KERNEL );
- if( !gPWM_Circ_Buf.buf ) {
- goto out;
- } else {
- // Initialize circular buffer
- gPWM_Circ_Buf.read = 0;
- gPWM_Circ_Buf.write = 0;
- gPWM_Circ_Buf.size = MAX_SOUND_BUFFER_SIZE*2;
- }
- }
+ if (count > MAX_SOUND_BUFFER_SIZE)
+ count = MAX_SOUND_BUFFER_SIZE;
+ /* First time, allocate the double buffer */
+ if (!gPWM_Circ_Buf.buf) {
+ gPWM_Circ_Buf.buf = kmalloc( count*2, GFP_KERNEL );
+ if (!gPWM_Circ_Buf.buf) {
+ goto out;
+ } else {
+ /* Initialize circular buffer */
+ gPWM_Circ_Buf.read = 0;
+ gPWM_Circ_Buf.write = 0;
+ gPWM_Circ_Buf.size = MAX_SOUND_BUFFER_SIZE*2;
+ }
+ }
- // If there is enough space at the end of the buffer for all data in one copy, do it
- remaining_space = gPWM_Circ_Buf.size - gPWM_Circ_Buf.write;
- pr_debug("Remaining space to end: %d, must write: %d \n", remaining_space, count);
- if( remaining_space >= count ) {
- // Get data from UserSpace
- if( copy_from_user( gPWM_Circ_Buf.buf + gPWM_Circ_Buf.write , buf, count ) ) {
- ret = -EFAULT; goto out;
- }
- increase_circbuf( &gPWM_Circ_Buf, count );
- // if not enough space, then
- } else {
- // Do it in 2 times
- if( copy_from_user( gPWM_Circ_Buf.buf + gPWM_Circ_Buf.write, buf, remaining_space ) ) {
- ret = -EFAULT; goto out;
- }
- increase_circbuf( &gPWM_Circ_Buf, remaining_space );
- if( copy_from_user( gPWM_Circ_Buf.buf + gPWM_Circ_Buf.write, buf, count - remaining_space ) ) {
- ret = -EFAULT; goto out;
- }
- increase_circbuf( &gPWM_Circ_Buf, count - remaining_space );
- }
+ /* If there is enough space at the end of the buffer for all data in one copy, do it */
+ remaining_space = gPWM_Circ_Buf.size - gPWM_Circ_Buf.write;
+ pr_debug("Remaining space to end: %d, must write: %d \n", remaining_space, count);
+ if (remaining_space >= count) {
+ // Get data from UserSpace
+ if( copy_from_user( gPWM_Circ_Buf.buf + gPWM_Circ_Buf.write , buf, count ) ) {
+ ret = -EFAULT; goto out;
+ }
+ increase_circbuf( &gPWM_Circ_Buf, count );
+ /* if not enough space, then */
+ } else {
+ /* Do it in 2 times */
+ if (copy_from_user(gPWM_Circ_Buf.buf + gPWM_Circ_Buf.write, buf, remaining_space)) {
+ ret = -EFAULT; goto out;
+ }
+ increase_circbuf( &gPWM_Circ_Buf, remaining_space );
+ if (copy_from_user(gPWM_Circ_Buf.buf + gPWM_Circ_Buf.write, buf, count - remaining_space)) {
+ ret = -EFAULT; goto out;
+ }
+ increase_circbuf(&gPWM_Circ_Buf, count - remaining_space);
+ }
- // Enable PWM
- PWMC |= PWMC_EN; PWMS = 0x00000000;
+ /* Enable PWM */
+ PWMC |= PWMC_EN;
+ PWMS = 0x00000000;
- if( gPwmMode == PWM_PLAY_MODE )
- {
- PWMC |= PWMC_IRQEN; // Enable IRQ
- }
- else
- {
- PWMS = gSampleValue;
- PWMC |= 0x7f00; // set prescaler to 128
-/* gpWriteBufPtr16 = (u16*)gpWriteBuf;
- gWriteCnt /= 2; //input size is 8bit size, need /2 to get 16bit size
- StartTimer( &pwmTimer );*/
- }
+ if (gPwmMode == PWM_PLAY_MODE) {
+ PWMC |= PWMC_IRQEN; /* Enable IRQ */
+ } else {
+ PWMS = gSampleValue;
+ PWMC |= 0x7f00; /* set prescaler to 128 */
+ /* gpWriteBufPtr16 = (u16*)gpWriteBuf;
+ gWriteCnt /= 2; //input size is 8bit size, need /2 to get 16bit size
+ StartTimer( &pwmTimer );*/
+ }
- // Calculate how much space is left in buffer
- remaining_space = CIRC_SPACE( gPWM_Circ_Buf.write, gPWM_Circ_Buf.read, gPWM_Circ_Buf.size );
- pr_debug("Space left: %d\n", remaining_space);
- if( remaining_space < count ) {
- // Pauses user app until interrupt handler has consumed some data
- interruptible_sleep_on( &write_wait );
- }
+ /* Calculate how much space is left in buffer */
+ remaining_space = CIRC_SPACE(gPWM_Circ_Buf.write, gPWM_Circ_Buf.read, gPWM_Circ_Buf.size);
+ pr_debug("Space left: %d\n", remaining_space);
+ if (remaining_space < count) {
+ /* Pauses user app until interrupt handler has consumed some data */
+ interruptible_sleep_on(&write_wait);
+ }
out:
- pr_debug( "out pwm_write PWMC = 0x%8x ----\n", PWMC );
- return count;
+ pr_debug( "out pwm_write PWMC = 0x%8x ----\n", PWMC );
+ return count;
}
-
struct file_operations pwm_fops = {
- open: pwm_open,
- release: pwm_release,
- read: pwm_read,
- write: pwm_write,
- ioctl: pwm_ioctl,
- fasync: pwm_fasync
+ open: pwm_open,
+ release: pwm_release,
+ read: pwm_read,
+ write: pwm_write,
+ ioctl: pwm_ioctl,
+ fasync: pwm_fasync
};
/////////////////////////////////////// END OF /DEV INTERFACE /////////////////////////////////////////////////////////
@@ -725,11 +621,12 @@
*/
static ssize_t pwm_show_duty(struct device *dev, struct device_attribute *attr, char *buf)
{
- ssize_t ret_size = 0;
- struct pwm_device *ppd = to_pwm_device(dev);
+ ssize_t ret_size = 0;
+ struct pwm_device *ppd = to_pwm_device(dev);
- ret_size=sprintf(buf,"%u",ppd->duty);
- return ret_size;
+ ret_size=sprintf(buf,"%u",ppd->duty);
+
+ return ret_size;
}
/**
@@ -747,17 +644,17 @@
*/
static ssize_t pwm_store_duty(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
- long value;
- struct pwm_device *ppd = to_pwm_device(dev);
+ long value;
+ struct pwm_device *ppd = to_pwm_device(dev);
- value = simple_strtol(buf, NULL, 10);
- if ((value < 1) || (value > 999))
- return -EIO;
+ value = simple_strtol(buf, NULL, 10);
+ if ((value < 1) || (value > 999))
+ return -EIO;
- ppd->duty=(unsigned)value;
+ ppd->duty=(unsigned)value;
+ setup_pwm_unit(ppd);
- setup_pwm_unit(ppd);
- return size;
+ return size;
}
/**
@@ -767,15 +664,15 @@
*/
static ssize_t pwm_show_period(struct device *dev, struct device_attribute *attr, char *buf)
{
- ssize_t ret_size = 0;
- struct pwm_device *ppd = to_pwm_device(dev);
+ ssize_t ret_size = 0;
+ struct pwm_device *ppd = to_pwm_device(dev);
- if (ppd->entry) /* already initialized? */
- ret_size=sprintf(buf,"%ld",ppd->entry->period);
- else
- ret_size=sprintf(buf,"0");
+ if (ppd->entry) /* already initialized? */
+ ret_size=sprintf(buf,"%ld",ppd->entry->period);
+ else
+ ret_size=sprintf(buf,"0");
- return ret_size;
+ return ret_size;
}
/**
@@ -808,13 +705,13 @@
#define PWM_MAX_FREQUENCY 100000 // Hz
static ssize_t pwm_store_period(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
- long value/*,i*/;
- struct pwm_device *ppd = to_pwm_device(dev);
+ long value/*,i*/;
+ struct pwm_device *ppd = to_pwm_device(dev);
+
+ value = simple_strtol(buf, NULL, 10);
+ if ((value < PWM_MIN_PERIOD) && (value > PWM_MAX_PERIOD))
+ return -EIO;
- value = simple_strtol(buf, NULL, 10);
- if ((value < PWM_MIN_PERIOD) && (value > PWM_MAX_PERIOD))
- return -EIO;
-
/* for( i=0; i<ARRAY_SIZE(pwm_table); i++ )
{
if (pwm_table[i].period >= value)
@@ -823,16 +720,16 @@
if (i==ARRAY_SIZE(pwm_table)) // period not found in table?
return -EIO;
- ppd->entry=&pwm_table[i];*/
- ppd->entry=&pwmdata;
- ppd->entry->period = value;
- ppd->entry->prescaler = 8; // 1us / tick if CLKSEL is = 0
- ppd->entry->max_period_val = value;
- /*printk(KERN_INFO "New period should be %ld us, and is %ld us\n",
- value,ppd->entry->period);*/
+ ppd->entry=&pwm_table[i];*/
+ ppd->entry=&pwmdata;
+ ppd->entry->period = value;
+ ppd->entry->prescaler = 8; // 1us / tick if CLKSEL is = 0
+ ppd->entry->max_period_val = value;
+ /*printk(KERN_INFO "New period should be %ld us, and is %ld us\n",
+ value,ppd->entry->period);*/
- setup_pwm_unit(ppd);
- return size;
+ setup_pwm_unit(ppd);
+ return size;
}
/**
@@ -842,15 +739,15 @@
*/
static ssize_t pwm_show_frequency(struct device *dev, struct device_attribute *attr, char *buf)
{
- ssize_t ret_size = 0;
- struct pwm_device *ppd = to_pwm_device(dev);
+ ssize_t ret_size = 0;
+ struct pwm_device *ppd = to_pwm_device(dev);
- if (ppd->entry)
- ret_size = sprintf( buf,"%ld", (u32) 1000000/(ppd->entry->period) );
- else
- ret_size = sprintf(buf,"0");
+ if (ppd->entry)
+ ret_size = sprintf(buf,"%ld", (u32) 1000000/(ppd->entry->period));
+ else
+ ret_size = sprintf(buf,"0");
- return ret_size;
+ return ret_size;
}
/**
@@ -867,24 +764,24 @@
static ssize_t pwm_store_frequency(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
- long value;
- struct pwm_device *ppd = to_pwm_device(dev);
+ long value;
+ struct pwm_device *ppd = to_pwm_device(dev);
- value = simple_strtol(buf, NULL, 10);
- if( (value < PWM_MIN_FREQUENCY) && (value > PWM_MAX_FREQUENCY) )
- return -EIO;
+ value = simple_strtol(buf, NULL, 10);
+ if( (value < PWM_MIN_FREQUENCY) && (value > PWM_MAX_FREQUENCY) )
+ return -EIO;
- // Convert frequency into period
- value = (u32) (1000000 / value);
- //
- ppd->entry=&pwmdata;
- ppd->entry->period = value;
- ppd->entry->prescaler = 8; // 1us / tick if CLKSEL is = 0
- ppd->entry->max_period_val = value;
- // Update hardware
- setup_pwm_unit(ppd);
+ /* Convert frequency into period */
+ value = (u32) (1000000 / value);
- return( size );
+ ppd->entry=&pwmdata;
+ ppd->entry->period = value;
+ ppd->entry->prescaler = 8; /* 1us / tick if CLKSEL is = 0 */
+ ppd->entry->max_period_val = value;
+ /* Update hardware */
+ setup_pwm_unit(ppd);
+
+ return( size );
}
/**
@@ -894,11 +791,12 @@
*/
static ssize_t pwm_show_state(struct device *dev, struct device_attribute *attr, char *buf)
{
- ssize_t ret_size = 0;
- struct pwm_device *ppd = to_pwm_device(dev);
+ ssize_t ret_size = 0;
+ struct pwm_device *ppd = to_pwm_device(dev);
- ret_size=sprintf(buf,"%d",ppd->active);
- return ret_size;
+ ret_size=sprintf(buf,"%d",ppd->active);
+
+ return ret_size;
}
/**
@@ -911,18 +809,18 @@
*/
static ssize_t pwm_store_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
- long value;
- struct pwm_device *ppd = to_pwm_device(dev);
+ long value;
+ struct pwm_device *ppd = to_pwm_device(dev);
- value = simple_strtol(buf, NULL, 10);
- if (value != 0)
- ppd->active=1;
- else
- ppd->active=0;
+ value = simple_strtol(buf, NULL, 10);
+ if (value != 0)
+ ppd->active=1;
+ else
+ ppd->active=0;
- setup_pwm_unit(ppd);
+ setup_pwm_unit(ppd);
- return size;
+ return size;
}
@@ -959,34 +857,34 @@
*/
static int init_userinterface(struct platform_device *pdev, u32 address)
{
- int rc = 0;
- struct pwm_device *ppd;
+ int rc = 0;
+ struct pwm_device *ppd;
- if (unlikely((ppd = kmalloc(sizeof(struct pwm_device), GFP_KERNEL)) == NULL)) {
+ if (unlikely((ppd = kmalloc(sizeof(struct pwm_device), GFP_KERNEL)) == NULL)) {
rc = -ENOMEM;
- goto error_malloc;
+ goto error_malloc;
}
- memset(&ppd->class_dev, 0, sizeof(struct device));
- ppd->class_dev.class = &pwm_class;
- ppd->class_dev.parent = &pdev->dev;
- snprintf(ppd->class_dev.bus_id, BUS_ID_SIZE, "pwm%i", pdev->id);
- ppd->reg=address;
- ppd->entry=NULL;
- ppd->active=0;
- ppd->duty=500; // = 50.O%
+ memset(&ppd->class_dev, 0, sizeof(struct device));
+ ppd->class_dev.class = &pwm_class;
+ ppd->class_dev.parent = &pdev->dev;
+ snprintf(ppd->class_dev.bus_id, BUS_ID_SIZE, "pwm%i", pdev->id);
+ ppd->reg=address;
+ ppd->entry=NULL;
+ ppd->active=0;
+ ppd->duty=500; /* = 50.O% */
- rc = device_register(&ppd->class_dev);
- if (unlikely(rc)) goto error_register;
+ rc = device_register(&ppd->class_dev);
+ if (unlikely(rc)) goto error_register;
- /* Register the attributes */
- rc |= device_create_file( &ppd->class_dev, &dev_attr_duty );
+ /* Register the attributes */
+ rc |= device_create_file(&ppd->class_dev, &dev_attr_duty);
if (unlikely(rc)) goto error_file;
- rc |= device_create_file( &ppd->class_dev, &dev_attr_period );
+ rc |= device_create_file(&ppd->class_dev, &dev_attr_period);
if (unlikely(rc)) goto error_file;
- rc |= device_create_file( &ppd->class_dev, &dev_attr_frequency );
+ rc |= device_create_file(&ppd->class_dev, &dev_attr_frequency);
if (unlikely(rc)) goto error_file;
- rc |= device_create_file( &ppd->class_dev, &dev_attr_active );
+ rc |= device_create_file(&ppd->class_dev, &dev_attr_active);
if (unlikely(rc)) goto error_file;
pdev->dev.driver_data=ppd;
@@ -1001,7 +899,7 @@
error_malloc:
return rc;
success:
- return 0;
+ return 0;
}
/*
@@ -1009,114 +907,97 @@
*/
static irqreturn_t pwm_interrupt(int irq, void *dev_id)
{
- u32 status;
- int remaining = 0;
+ u32 status;
+ int remaining = 0;
- /* Acknowledge interrupt */
- status = PWMC;
+ /* Acknowledge interrupt */
+ status = PWMC;
- remaining = CIRC_CNT( gPWM_Circ_Buf.write, gPWM_Circ_Buf.read, gPWM_Circ_Buf.size );
- if( remaining <= 1024 && remaining > 1021 ) { // TODO make it better (I think a test each consumed sample is the only accurate solution
- // Can accept new data now
- wake_up_interruptible( &write_wait );
- }
+ remaining = CIRC_CNT( gPWM_Circ_Buf.write, gPWM_Circ_Buf.read, gPWM_Circ_Buf.size );
+ if( remaining <= 1024 && remaining > 1021 ) { // TODO make it better (I think a test each consumed sample is the only accurate solution
+ // Can accept new data now
+ wake_up_interruptible( &write_wait );
+ }
- /* End of sound buffer */
- if( remaining < 3 )
- {
- if(gDataLen == PWM_DATA_8BIT)
- {
- while( remaining )
- {
- PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
- /*PK("<1>(%d) pwm_int: PWMS = 0x%8x\n", gWriteCnt, PWMS);*/
- remaining--;
- }
- }
- else // if(gDataLen == PWM_DATA_16BIT) // one comparaison is enough
- {
- while( remaining )
- {
- PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
- //PK("<1>(%d) pwm_int: PWMS = 0x%8x\n", gWriteCnt, PWMS);
- remaining--;
- }
- }
+ /* End of sound buffer */
+ if( remaining < 3 ) {
+ if(gDataLen == PWM_DATA_8BIT) {
+ while( remaining ) {
+ PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
+ /*PK("<1>(%d) pwm_int: PWMS = 0x%8x\n", gWriteCnt, PWMS);*/
+ remaining--;
+ }
+ } else { /* PWM_DATA_16BIT) */
+ while( remaining ) {
+ PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
+ //PK("<1>(%d) pwm_int: PWMS = 0x%8x\n", gWriteCnt, PWMS);
+ remaining--;
+ }
+ }
- StopPwm();
- goto end;
- }
+ stop_pwm();
+ goto end;
+ }
- /* Put sound samples in FIFO */
- if(gDataLen == PWM_DATA_8BIT)
- {
- PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
- PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
- PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
- if (PWMC & PWMC_FIFOAV) // TODO: verify if needed
- {
- PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
- g4bytes++;
- }
- }
- else // if(gDataLen == PWM_DATA_16BIT) // one comparaison is enough
- {
- // TODO: put good value in PWMC_BCTR to auto swap bytes if needed (do it at write or ioctl)
- PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
- PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
- PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
- if (PWMC & PWMC_FIFOAV) // TODO: verify if needed
- {
- PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
- g4bytes++;
- }
- }
+ /* Put sound samples in FIFO */
+ if (gDataLen == PWM_DATA_8BIT) {
+ PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
+ PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
+ PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
+ if (PWMC & PWMC_FIFOAV) { /* TODO: verify if needed */
+ PWMS = (u32)(get_byte_from_circbuf( &gPWM_Circ_Buf ));
+ g4bytes++;
+ }
+ } else { /* PWM_DATA_16BIT) */
+ // TODO: put good value in PWMC_BCTR to auto swap bytes if needed (do it at write or ioctl)
+ PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
+ PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
+ PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
+ if (PWMC & PWMC_FIFOAV) { /* TODO: verify if needed */
+ PWMS = (u32)(get_word_from_circbuf( &gPWM_Circ_Buf ));
+ g4bytes++;
+ }
+ }
end:
- return(IRQ_HANDLED);
+ return(IRQ_HANDLED);
}
-/*
- *
- */
static int __init pwm_init_from_probe(void)
{
- int result;
+ int result;
- /* Register our char device */
- result = register_chrdev(0, DRIVER_NAME, &pwm_fops);
- if ( result < 0 )
- {
- printk("pwm driver: Unable to register driver\n");
- goto end;
- }
- /* Dynamic Major allocation */
- if( gMajor == 0 )
- {
- gMajor = result;
- printk("PWM major number = %d\n",gMajor);
- }
+ /* Register our char device */
+ result = register_chrdev(0, DRIVER_NAME, &pwm_fops);
+ if (result < 0) {
+ printk("pwm driver: Unable to register driver\n");
+ goto end;
+ }
+ /* Dynamic Major allocation */
+ if (gMajor == 0) {
+ gMajor = result;
+ printk("PWM major number = %d\n",gMajor);
+ }
- result = request_irq(PWM_INT, pwm_interrupt, IRQF_DISABLED, DEV_IRQ_NAME, DEV_IRQ_ID);
- if (result)
- {
- printk("<1>cannot init major= %d irq=%d\n", gMajor, irq);
- unregister_chrdev(gMajor, DRIVER_NAME);
- goto end;
- }
+ result = request_irq(PWM_INT, pwm_interrupt, IRQF_DISABLED, DEV_IRQ_NAME, DEV_IRQ_ID);
+ if (result) {
+ printk("<1>cannot init major= %d irq=%d\n", gMajor, irq);
+ unregister_chrdev(gMajor, DRIVER_NAME);
+ goto end;
+ }
- /* init wait queue */
- init_waitqueue_head(&write_wait);
- init_waitqueue_head(&exit_wait);
- pr_debug("Wait queues initialized\n");
+ /* init wait queue */
+ init_waitqueue_head(&write_wait);
+ init_waitqueue_head(&exit_wait);
+ pr_debug("Wait queues initialized\n");
- /* init PWM hardware module */
- initPWM();
+ /* init PWM hardware module */
+ init_pwm();
- printk("i.MX PWM driver v" DRIVER_VERSION "\n");
+ printk("i.MX PWM driver v" DRIVER_VERSION "\n");
end:
- return( result );
+ return( result );
}
/**
@@ -1132,45 +1013,45 @@
*/
static int imx_pwm_drv_probe(struct platform_device *pdev)
{
- int err=-ENODEV;
- struct resource *res;
+ int err=-ENODEV;
+ struct resource *res;
- printk(KERN_INFO " Initializing PWM#%u...",pdev->id);
+ printk(KERN_INFO " Initializing PWM#%u...",pdev->id);
- switch( pdev->id )
- {
- /* PWM0 */
- case 0:
- // Check if GPIO was initialized ??
- break;
+ switch( pdev->id )
+ {
+ /* PWM0 */
+ case 0:
+ // Check if GPIO was initialized ??
+ break;
+
+ default:
+ printk(DRIVER_NAME " failed. Unknown PWM%u device. Remember that this device only supports 1 PWM\n", pdev->id);
+ return err;
+ break;
+ }
- default:
- printk(DRIVER_NAME " failed. Unknown PWM%u device. Remember that this device only supports 1 PWM\n", pdev->id);
- return err;
- break;
- }
+ if (unlikely(!(res = platform_get_resource(pdev, IORESOURCE_MEM, 0))))
+ goto exit;
- if (unlikely(!(res = platform_get_resource(pdev, IORESOURCE_MEM, 0))))
- goto exit;
+ if (unlikely(!request_mem_region( res->start, res->end - res->start + 1, "imx-pwm" ))) {
+ err = -EBUSY;
+ goto exit;
+ }
+ pwm_init_from_probe();
- if (unlikely(!request_mem_region( res->start, res->end - res->start + 1, "imx-pwm" ))) {
- err = -EBUSY;
- goto exit;
- }
- pwm_init_from_probe();
+ /* Create /sys stuf */
+ if (unlikely((err=init_userinterface(pdev,res->start))))
+ goto release;
- /* Create /sys stuf */
- if (unlikely((err=init_userinterface(pdev,res->start))))
- goto release;
+ printk("done.\n");
+ return(0);
- printk("done.\n");
- return(0);
-
release:
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, res->end - res->start + 1);
exit:
- printk(KERN_INFO "not available.\n");
- return err;
+ printk(KERN_INFO "not available.\n");
+ return err;
}
static inline void unregister_sys_file( struct pwm_device *ppd )
@@ -1188,17 +1069,17 @@
*/
static int imx_pwm_drv_remove (struct platform_device *pdev)
{
- struct resource *res;
- struct pwm_device *ppd=(struct pwm_device*)pdev->dev.driver_data;
+ struct resource *res;
+ struct pwm_device *ppd=(struct pwm_device*)pdev->dev.driver_data;
unregister_sys_file(ppd);
device_unregister( &ppd->class_dev );
- kfree(ppd);
+ kfree(ppd);
- res = platform_get_resource( pdev, IORESOURCE_MEM, 0 );
- release_mem_region( res->start, res->end - res->start + 1 );
+ res = platform_get_resource( pdev, IORESOURCE_MEM, 0 );
+ release_mem_region( res->start, res->end - res->start + 1 );
- return 0;
+ return 0;
}
#ifdef CONFIG_PM
@@ -1209,8 +1090,8 @@
*/
static int imx_pwm_drv_suspend (struct platform_device *pdev, pm_message_t state)
{
- printk("%s\n",__FUNCTION__);
- return 0;
+ printk("%s\n",__FUNCTION__);
+ return 0;
}
/**
@@ -1219,8 +1100,8 @@
*/
static int imx_pwm_drv_resume (struct platform_device *pdev)
{
- printk("%s\n",__FUNCTION__);
- return 0;
+ printk("%s\n",__FUNCTION__);
+ return 0;
}
#else
@@ -1235,17 +1116,17 @@
*/
static void pwm_class_release(struct device *dev)
{
- return;
+ return;
}
static struct platform_driver imx_pwm_driver = {
- .probe = imx_pwm_drv_probe,
- .remove = imx_pwm_drv_remove,
- .suspend = imx_pwm_drv_suspend,
- .resume = imx_pwm_drv_resume,
- .driver = {
- .name = DRIVER_NAME,
- },
+ .probe = imx_pwm_drv_probe,
+ .remove = imx_pwm_drv_remove,
+ .suspend = imx_pwm_drv_suspend,
+ .resume = imx_pwm_drv_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ },
};
@@ -1254,8 +1135,8 @@
};
static struct sys_device pwm_sys_device = {
- .id = 0,
- .cls = &pwm_sysclass,
+ .id = 0,
+ .cls = &pwm_sysclass,
};
static struct class pwm_class = {
@@ -1264,55 +1145,49 @@
};
-/*
- * Called when module is insmoded
- */
-int __init imx_pwm_init(void)
+static int __init imx_pwm_init(void)
{
- int ret;
+ int ret;
- printk(KERN_INFO "Initializing PWM class.\n");
+ printk(KERN_INFO "Initializing PWM class.\n");
- if (unlikely((ret = class_register(&pwm_class)))) {
- printk(KERN_ERR "%s: couldn't register class, exiting\n", DRIVER_NAME);
- return ret;
- }
+ if (unlikely((ret = class_register(&pwm_class)))) {
+ printk(KERN_ERR "%s: couldn't register class, exiting\n", DRIVER_NAME);
+ return ret;
+ }
- if (unlikely((ret = sysdev_class_register(&pwm_sysclass)))) {
- printk(KERN_ERR "%s: couldn't register sysdev class, exiting\n", DRIVER_NAME);
- goto out_sysdev_class;
- }
+ if (unlikely((ret = sysdev_class_register(&pwm_sysclass)))) {
+ printk(KERN_ERR "%s: couldn't register sysdev class, exiting\n", DRIVER_NAME);
+ goto out_sysdev_class;
+ }
- if (unlikely((ret = sysdev_register(&pwm_sys_device)))) {
- printk(KERN_ERR "%s: couldn't register sysdev, exiting\n", DRIVER_NAME);
- goto out_sysdev_register;
- }
+ if (unlikely((ret = sysdev_register(&pwm_sys_device)))) {
+ printk(KERN_ERR "%s: couldn't register sysdev, exiting\n", DRIVER_NAME);
+ goto out_sysdev_register;
+ }
- return platform_driver_register( &imx_pwm_driver );
+ return platform_driver_register(&imx_pwm_driver);
out_sysdev_register:
- sysdev_class_unregister( &pwm_sysclass );
+ sysdev_class_unregister(&pwm_sysclass);
out_sysdev_class:
- class_unregister( &pwm_class );
+ class_unregister(&pwm_class);
- return ret;
+ return ret;
}
-/*
- * Called when module is rmmoded
- */
-void __exit imx_pwm_exit(void)
+static void __exit imx_pwm_exit(void)
{
- disable_irq( PWM_INT ); // should be done before free_irq no ?
- free_irq( PWM_INT, DEV_IRQ_ID );
- unregister_chrdev( gMajor, DRIVER_NAME );
+ disable_irq(PWM_INT); /* should be done before free_irq no ? */
+ free_irq(PWM_INT, DEV_IRQ_ID);
+ unregister_chrdev(gMajor, DRIVER_NAME);
- platform_driver_unregister( &imx_pwm_driver );
- sysdev_unregister( &pwm_sys_device );
- sysdev_class_unregister( &pwm_sysclass );
- class_unregister( &pwm_class );
+ platform_driver_unregister(&imx_pwm_driver);
+ sysdev_unregister(&pwm_sys_device);
+ sysdev_class_unregister(&pwm_sysclass);
+ class_unregister(&pwm_class);
- printk( DRIVER_NAME " successfully unloaded\n" );
+ printk(DRIVER_NAME " successfully unloaded\n");
}
module_init(imx_pwm_init);
@@ -1320,4 +1195,3 @@
MODULE_AUTHOR("Julien Boibessot & Sebastien Royen, inspired by a lot of other PWM drivers");
MODULE_DESCRIPTION("i.MX PWM driver");
MODULE_LICENSE("GPL");
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|