[Armadeus-commitlog] armadeus branch, master, updated. release-3.2-245-g17ccf2b
Brought to you by:
sszy
|
From: Julien B a. A. <ar...@us...> - 2010-03-18 15:57:48
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via 17ccf2b88b5aefd5e34263957f6636621bd4d442 (commit)
via c8d8b8571e91d7c5f394aa83d1a78693b866c7fd (commit)
via 1383d69b3440c1cb5e5a8b2bcd2829c311575807 (commit)
via 59487a64ccd11fbc1ee8815145c697a18e1bca51 (commit)
via e6e6e857d141e1fee87806fb6d72bd90f7d9759e (commit)
from 927b7a7bb2772e43c3c6d50d769ed9e8e09e3424 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 17ccf2b88b5aefd5e34263957f6636621bd4d442
Author: Julien Boibessot <jul...@ar...>
Date: Thu Mar 18 16:56:49 2010 +0100
[TESTS] Transform test_pwm.sh in a release test
commit c8d8b8571e91d7c5f394aa83d1a78693b866c7fd
Author: Julien Boibessot <jul...@ar...>
Date: Thu Mar 18 16:31:28 2010 +0100
[TESTS] Move test_pwm.sh to the test scripts dir
commit 1383d69b3440c1cb5e5a8b2bcd2829c311575807
Author: Julien Boibessot <jul...@ar...>
Date: Thu Mar 18 16:28:58 2010 +0100
[TESTS] Rename testpwm.sh to test_pwm.sh
commit 59487a64ccd11fbc1ee8815145c697a18e1bca51
Author: Julien Boibessot <jul...@ar...>
Date: Thu Mar 18 13:27:45 2010 +0100
[LINUX] Cleanup PWM driver & add automatic /dev creation
commit e6e6e857d141e1fee87806fb6d72bd90f7d9759e
Author: Julien Boibessot <jul...@ar...>
Date: Wed Mar 17 11:52:43 2010 +0100
[DEMOS] Cleanup in oscillo & real_time/fractal
-----------------------------------------------------------------------
Summary of changes:
target/demos/oscillo/lcd.c | 10 -
target/demos/real_time/fractal/lcd.c | 10 -
target/linux/modules/pwm/pwm.c | 415 ++++++++++-------------------
target/linux/modules/pwm/pwm.h | 94 ++++----
target/linux/modules/pwm/test/test_pwm.sh | 1 +
target/linux/modules/pwm/test/testpwm.sh | 47 ----
target/test/test_pwm.sh | 92 +++++++
target/test/test_release.sh | 2 +
8 files changed, 280 insertions(+), 391 deletions(-)
create mode 120000 target/linux/modules/pwm/test/test_pwm.sh
delete mode 100755 target/linux/modules/pwm/test/testpwm.sh
create mode 100755 target/test/test_pwm.sh
diff --git a/target/demos/oscillo/lcd.c b/target/demos/oscillo/lcd.c
index db1e0c7..cb5ea5d 100644
--- a/target/demos/oscillo/lcd.c
+++ b/target/demos/oscillo/lcd.c
@@ -21,26 +21,16 @@
*
*/
-
#include <errno.h>
-
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <ctype.h>
-
#include <sys/ioctl.h>
#include <sys/time.h>
-#include <unistd.h>
-#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
-#include <sys/mman.h>
#include "lcd.h"
diff --git a/target/demos/real_time/fractal/lcd.c b/target/demos/real_time/fractal/lcd.c
index d6072be..534428e 100644
--- a/target/demos/real_time/fractal/lcd.c
+++ b/target/demos/real_time/fractal/lcd.c
@@ -21,26 +21,16 @@
*
*/
-
#include <errno.h>
-
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <ctype.h>
-
#include <sys/ioctl.h>
#include <sys/time.h>
-#include <unistd.h>
-#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
-#include <sys/mman.h>
#include "lcd.h"
diff --git a/target/linux/modules/pwm/pwm.c b/target/linux/modules/pwm/pwm.c
index 2fca2ad..82c686e 100644
--- a/target/linux/modules/pwm/pwm.c
+++ b/target/linux/modules/pwm/pwm.c
@@ -21,25 +21,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
+
#include <linux/module.h>
#include <linux/version.h>
-#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
-#include <linux/poll.h>
-#include <asm/uaccess.h> /* get_user,copy_to_user */
+#include <asm/uaccess.h> /* get_user, copy_to_user */
#include <linux/miscdevice.h>
-
-#include <linux/string.h>
-#include <linux/kernel.h>
#include <linux/timer.h>
-#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/string.h>
#include <asm/io.h>
#include <mach/hardware.h>
#include <linux/errno.h>
@@ -47,8 +39,7 @@
#include <linux/pm.h>
#include <linux/clk.h>
#include <linux/sysdev.h>
-/* For struct class */
-#include <linux/device.h>
+#include <linux/device.h> /* struct class */
#include <linux/circ_buf.h>
#include <linux/platform_device.h>
@@ -119,10 +110,8 @@
#endif
#define DRIVER_NAME "imx-pwm"
-#define DRIVER_VERSION "0.7"
+#define DRIVER_VERSION "0.8"
-//#define PK(fmt, args...) printk(fmt, ## args)
-#define PK(...)
struct sound_circ_buf {
char* buf;
@@ -142,18 +131,16 @@ typedef struct timerStruct
int stop_flag;
} pwm_timer_t;
-
-struct pwm_table {
- u32 period; /* in us */
- u32 prescaler;
-};
-
struct pwm_device {
- unsigned long membase;
+ void __iomem *membase;
unsigned int irq;
+
int active;
- unsigned duty;
- /*const*/ struct pwm_table entry;
+ unsigned int duty; /* current duty cycle in % x 10 */
+ unsigned int frequency; /* current frequency in Hz */
+ u16 prescaler;
+ u16 period_reg; /* value to put in PWMPR register to have requested freq */
+
int mode;
int nbbytes; /* count 4 bytes write occurence to FIFO */
int dataLen;
@@ -167,23 +154,21 @@ struct pwm_device {
timer_blk_t timer_blk;
struct clk *clk;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
- struct class_device class_dev;
-#else
- struct device class_dev;
-#endif
+ struct device *dev;
};
int gMajor = 0;
-static struct pwm_device *dev_table[PWM_MAX_DEV];
-static struct class pwm_class; /* forward declaration only */
+static struct pwm_device *dev_table[PWM_MAX_DEV];
+static struct class *pwm_class; /* forward declaration only */
-#define to_pwm_device(d) container_of(d, struct pwm_device, class_dev)
+static void inline unregister_sys_file(struct pwm_device *pwm);
-//struct fasync_struct *ts_fasync;
+/*
+struct fasync_struct *ts_fasync;
+*/
/****************************************************************
- * Circular buffer handling four sound playing
+ * Circular buffer handling for sound playing
***************************************************************/
static inline u8 get_byte_from_circbuf(struct sound_circ_buf* abuffer)
@@ -214,6 +199,7 @@ static inline void increase_circbuf(struct sound_circ_buf* abuffer, int count)
pr_debug("Added %d bytes to buffer, now write is in pos %d\n", count, abuffer->write);
}
+
static int get_current_pwm_clk_rate(struct pwm_device *pwm)
{
if ((readl(pwm->membase + PWMCTRL) & PWM_CLKSRC_MASK) == PWM_CLKSRC_32K)
@@ -243,26 +229,21 @@ static void compute_pwm_params(u32 req_freq, struct pwm_device *pwm)
u32 input_freq, divider;
input_freq = get_current_pwm_clk_rate(pwm);
-// printk("input freq, %x %x\n", input_freq, req_freq);
+ pr_debug("input freq, %d %d\n", input_freq, req_freq);
divider = ((input_freq*10)/req_freq+5)/10;
if (divider/65536) {
- pwm->entry.prescaler = divider/65536 +1;
- pwm->entry.period = input_freq/(pwm->entry.prescaler*req_freq)-2;
+ pwm->prescaler = (divider/65536)+1;
+ pwm->period_reg = input_freq/(pwm->prescaler*req_freq)-2;
} else {
- pwm->entry.period = divider-2;
- pwm->entry.prescaler = 1;
+ pwm->period_reg = divider-2;
+ pwm->prescaler = 1;
}
+ pwm->frequency = req_freq;
+ pr_debug("period: %d prescaler: %d\n", pwm->period_reg, pwm->prescaler);
}
-/****************************************************************
- *
- ***************************************************************/
-
-static void inline unregister_sys_file( struct pwm_device *pwm );
-
-
-static void write_bits(u32 bit, u32 mask, unsigned long reg)
+static void write_bits(u32 bit, u32 mask, void __iomem *reg)
{
u32 temp;
temp = readl(reg) & ~mask;
@@ -273,21 +254,17 @@ static void setup_pwm_params(struct pwm_device *pwm)
{
write_bits(PWM_CLKSRC_IPG, PWM_CLKSRC_MASK, pwm->membase + PWMCTRL);
/* Setup prescaler */
- pr_debug("Updating PWM registers\n");
- write_bits(PWM_PRESCALER(pwm->entry.prescaler),
+ write_bits(PWM_PRESCALER(pwm->prescaler),
PWM_PRESCALER_MASK, pwm->membase + PWMCTRL); /*| PWMC_REPEAT(3)*/;
/* Setup period */
- writel(PWM_PERIOD(pwm->entry.period), pwm->membase + PWMPERIOD);
+ writel(PWM_PERIOD(pwm->period_reg), pwm->membase + PWMPERIOD);
/* Setup duty cycle */
- writel(PWM_SAMPLE((u32)((pwm->entry.period * pwm->duty) / 1000)),
+ writel(PWM_SAMPLE((u32)((pwm->period_reg * pwm->duty) / 1000)),
pwm->membase + PWMSAMPLE);
}
-/**
- * setup_pwm_unit - common setup function whenever something was changed
- * @pwm: PWM unit to work with
- */
+/* common setup function whenever something was changed */
static void setup_pwm_unit(struct pwm_device *pwm)
{
if (pwm->active) {
@@ -309,6 +286,7 @@ static int create_timer(pwm_timer_t *timer)
return 0;
}
+#if 0
static int start_timer(pwm_timer_t *timer)
{
timer->timer_blk_ptr->expires = jiffies + timer->period;
@@ -318,6 +296,7 @@ static int start_timer(pwm_timer_t *timer)
return 0;
}
+#endif
static int stop_timer(pwm_timer_t *timer)
{
@@ -339,15 +318,15 @@ static void stop_pwm(struct pwm_device *pwm)
/* Can release file now */
wake_up_interruptible(&pwm->exit_wait);
- PK("<1>data completed.\n");
- PK("<1>PWMC = 0x%8x\n", readl(pwm->membase + PWMCTRL));
+ pr_debug("data completed.\n");
+ pr_debug("PWMC = 0x%8x\n", readl(pwm->membase + PWMCTRL));
}
static void pwmIntFunc( unsigned long unused)
{
// u32 period;
- PK("<1>pwm sam int\n");
+ pr_debug("pwm sam int\n");
// if (gWriteCnt > 0)
// {
@@ -383,13 +362,14 @@ static int init_pwm(struct pwm_device *pwm)
return 1;
}
-//////////////////////////////////////// /DEV INTERFACE ////////////////////////////////////////////
+
+/* /DEV INTERFACE */
int pwm_release(struct inode * inode, struct file * filp)
{
struct pwm_device *pwm = dev_table[iminor(inode)];
- // wait unit gWriteCnt == 0
+ /* wait unit gWriteCnt == 0 */
interruptible_sleep_on(&pwm->exit_wait);
if (pwm->mode == PWM_PLAY_MODE) {
/* disable IRQ */
@@ -423,7 +403,7 @@ int pwm_open(struct inode * inode, struct file * filp)
static int pwm_fasync(int fd, struct file *filp, int mode)
{
- PK("<1>in pwm_fasyn ----\n");
+ pr_debug("in pwm_fasyn ----\n");
#if 0
/* TODO TODO put this data into file private data */
int minor = checkDevice( filp->f_dentry->d_inode);
@@ -435,7 +415,7 @@ static int pwm_fasync(int fd, struct file *filp, int mode)
return( fasync_helper(fd, filp, mode, &ts_fasync) );
#endif
- return 0;
+ return 0;
}
int pwm_ioctl(struct inode * inode, struct file *filp, unsigned int cmd, unsigned long arg)
@@ -444,9 +424,7 @@ int pwm_ioctl(struct inode * inode, struct file *filp, unsigned int cmd, unsigne
int ret = 0;
struct pwm_device *pwm = dev_table[iminor(inode)];
- pr_debug("pwm_ioctl ----\n");
- switch(cmd)
- {
+ switch (cmd) {
/* Set PWM Mode (Tone or Playback) */
case PWM_IOC_SMODE:
{
@@ -528,7 +506,7 @@ int pwm_ioctl(struct inode * inode, struct file *filp, unsigned int cmd, unsigne
case PWM_IOC_SPERIOD:
if (pwm->mode == PWM_TONE_MODE) {
- PK("<1>PWM period = %d\n",(int)arg);
+ pr_debug("PWM period = %d\n", (int)arg);
pwm->timer.period = arg/12;
}
break;
@@ -570,8 +548,6 @@ ssize_t pwm_read(struct file * filp, char * buf, size_t count, loff_t * l)
else
ret = 0; /* processing data */
- pr_debug("pwm_read ----\n");
-
return ret;
}
@@ -582,8 +558,6 @@ static ssize_t pwm_write( struct file *filp, const char *buf, size_t count, loff
struct pwm_device *pwm = dev_table[iminor(filp->f_dentry->d_inode)];
struct sound_circ_buf *circ = &pwm->circ_buf;
- pr_debug("pwm_write ----\n");
-
if (count > MAX_SOUND_BUFFER_SIZE)
count = MAX_SOUND_BUFFER_SIZE;
/* First time, allocate the double buffer */
@@ -661,32 +635,22 @@ struct file_operations pwm_fops = {
fasync: pwm_fasync
};
-/////////////////////////////////////// END OF /DEV INTERFACE /////////////////////////////////////////////////////////
+/* END OF /DEV INTERFACE */
-/**
- * pwm_show_duty - return current duty setting
- * @dev: device to work with
- * @buf: space to write the current value in
- */
+/* /sys interface: */
+
static ssize_t pwm_show_duty(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t ret_size = 0;
- struct pwm_device *pwm = to_pwm_device(dev);
+ struct pwm_device *pwm = dev_get_drvdata(dev);
- ret_size=sprintf(buf, "%u", pwm->duty);
+ ret_size = sprintf(buf, "%u", pwm->duty);
return ret_size;
}
-/**
- * pwm_store_duty - set new duty
- * @dev: device to work with
- * @buf: buffer with new value in ASCII
- * @size: size of buffer
- *
- * Returns the given @size or -EIO
- *
+/*
* Duty value can be 0 ... 1000. Without floating point you can take
* one position after decimal point into account. The internal counters
* supports 10 bit resolution, so it makes sense to support such a thing
@@ -695,7 +659,7 @@ static ssize_t pwm_show_duty(struct device *dev, struct device_attribute *attr,
static ssize_t pwm_store_duty(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
long value;
- struct pwm_device *pwm = to_pwm_device(dev);
+ struct pwm_device *pwm = dev_get_drvdata(dev);
value = simple_strtol(buf, NULL, 10);
if ((value < 1) || (value > 999))
@@ -707,34 +671,23 @@ static ssize_t pwm_store_duty(struct device *dev, struct device_attribute *attr,
return size;
}
-/**
- * pwm_show_period - return current period setting
- * @dev: device to work with
- * @buf: space to write the current value in
- */
static ssize_t pwm_show_period(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t ret_size = 0;
- struct pwm_device *pwm = to_pwm_device(dev);
+ struct pwm_device *pwm = dev_get_drvdata(dev);
- ret_size = sprintf(buf, "%d", pwm->entry.period);
+ if (pwm->frequency)
+ ret_size = sprintf(buf, "%d", (u32) 1000000/(pwm->frequency));
+ else
+ ret_size = sprintf(buf, "0");
return ret_size;
}
-/**
- * pwm_store_period - set new period setting
- * @dev: device to work with
- * @buf: buffer with new value in ASCII
- * @size: size of buffer
- *
- * Returns the given @size or -EIO
- */
-
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 *pwm = to_pwm_device(dev);
+ long value;
+ struct pwm_device *pwm = dev_get_drvdata(dev);
value = simple_strtol(buf, NULL, 10); /* in us */
if ((value < (1000000/get_pwm_max_freq(pwm))) || (value > (1000000/get_pwm_min_freq(pwm))))
@@ -746,40 +699,24 @@ static ssize_t pwm_store_period(struct device *dev, struct device_attribute *att
return size;
}
-/**
- * pwm_show_frequency - return current frequency setting
- * @dev: device to work with
- * @buf: space to write the current value in
- */
static ssize_t pwm_show_frequency(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t ret_size = 0;
- struct pwm_device *pwm = to_pwm_device(dev);
+ struct pwm_device *pwm = dev_get_drvdata(dev);
- if (pwm->entry.period)
- ret_size = sprintf(buf, "%d", (u32) 1000000/(pwm->entry.period));
- else
- ret_size = sprintf(buf, "0");
+ ret_size = sprintf(buf, "%d", pwm->frequency);
return ret_size;
}
-/**
- * pwm_store_frequency - set new frequency setting
- * @dev: device to work with
- * @buf: buffer with new value in ASCII
- * @size: size of buffer
- *
- * Returns the given @size or -EIO
- *
- * The unit of the given value should be in Hertz and the value
- * between 2 and 100k.
+/*
+ * Given value (in Hertz) should be between 2 and 100k
*/
static ssize_t pwm_store_frequency(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
long value;
- struct pwm_device *pwm = to_pwm_device(dev);
+ struct pwm_device *pwm = dev_get_drvdata(dev);
value = simple_strtol(buf, NULL, 10);
if ((value < get_pwm_min_freq(pwm)) || (value > get_pwm_max_freq(pwm)))
@@ -791,33 +728,20 @@ static ssize_t pwm_store_frequency(struct device *dev, struct device_attribute *
return size;
}
-/**
- * pwm_show_state - return current state setting
- * @dev: device to work with
- * @buf: space to write the current value in
- */
static ssize_t pwm_show_state(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t ret_size = 0;
- struct pwm_device *pwm = to_pwm_device(dev);
+ struct pwm_device *pwm = dev_get_drvdata(dev);
ret_size = sprintf(buf, "%d", pwm->active);
return ret_size;
}
-/**
- * pwm_store_state - set new state setting
- * @dev: device to work with
- * @buf: buffer with new value in ASCII
- * @size: size of buffer
- *
- * Returns the given @size
- */
static ssize_t pwm_store_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
long value;
- struct pwm_device *pwm = to_pwm_device(dev);
+ struct pwm_device *pwm = dev_get_drvdata(dev);
value = simple_strtol(buf, NULL, 10);
if (value != 0)
@@ -830,29 +754,13 @@ static ssize_t pwm_store_state(struct device *dev, struct device_attribute *attr
return size;
}
-
-/*
- * Attribute: /sys/class/pwm/pwmX/duty
- * dev_attr_duty
- */
+/* dev_attr_duty /class/pwm/pwmX/duty */
static DEVICE_ATTR(duty, S_IWUSR | S_IRUGO, pwm_show_duty, pwm_store_duty);
-
-/*
- * Attribute: /sys/class/pwm/pwmX/period
- * dev_attr_period
- */
+/* dev_attr_period /sys/class/pwm/pwmX/period */
static DEVICE_ATTR(period, S_IWUSR | S_IRUGO, pwm_show_period, pwm_store_period);
-
-/*
- * Attribute: /sys/class/pwm/pwmX/frequency
- * dev_attr_frequency
- */
+/* dev_attr_frequency /sys/class/pwm/pwmX/frequency */
static DEVICE_ATTR(frequency, S_IWUSR | S_IRUGO, pwm_show_frequency, pwm_store_frequency);
-
-/*
- * Attribute: /sys/class/pwm/pwmX/active
- * dev_attr_active
- */
+/* dev_attr_active /sys/class/pwm/pwmX/active */
static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, pwm_show_state, pwm_store_state);
@@ -861,7 +769,9 @@ static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, pwm_show_state, pwm_store_state);
*/
static irqreturn_t pwm_interrupt(int irq, void *dev_id)
{
+#ifndef CONFIG_ARCH_MX2
u32 status;
+#endif
int remaining = 0;
struct pwm_device *pwm = (struct pwm_device *) dev_id;
@@ -882,13 +792,13 @@ static irqreturn_t pwm_interrupt(int irq, void *dev_id)
if (pwm->dataLen == PWM_DATA_8BIT) {
while (remaining) {
writel((u32)(get_byte_from_circbuf(&pwm->circ_buf)), pwm->membase + PWMSAMPLE);
- /*PK("<1>(%d) pwm_int: PWMS = 0x%8x\n", gWriteCnt, PWMS);*/
+ /*pr_debug("(%d) pwm_int: PWMS = 0x%8x\n", gWriteCnt, PWMS);*/
remaining--;
}
} else { /* PWM_DATA_16BIT) */
while (remaining) {
writel((u32)(get_word_from_circbuf(&pwm->circ_buf)), pwm->membase + PWMSAMPLE);
- //PK("<1>(%d) pwm_int: PWMS = 0x%8x\n", gWriteCnt, PWMS);
+ /*pr_debug("(%d) pwm_int: PWMS = 0x%8x\n", gWriteCnt, PWMS); */
remaining--;
}
}
@@ -911,7 +821,7 @@ static irqreturn_t pwm_interrupt(int irq, void *dev_id)
}
#endif
} else { /* PWM_DATA_16BIT) */
- // TODO: put good value in PWMC_BCTR to auto swap bytes if needed (do it at write or ioctl)
+ /* TODO: put good value in PWMC_BCTR to auto swap bytes if needed (do it at write or ioctl) */
writel((u32)(get_word_from_circbuf(&pwm->circ_buf)), pwm->membase + PWMSAMPLE);
writel((u32)(get_word_from_circbuf(&pwm->circ_buf)), pwm->membase + PWMSAMPLE);
writel((u32)(get_word_from_circbuf(&pwm->circ_buf)), pwm->membase + PWMSAMPLE);
@@ -925,80 +835,76 @@ end:
return IRQ_HANDLED;
}
-/**
- * imx_pwm_drv_probe - claim resources
- * @pdev: platform device to work with
- */
static int imx_pwm_drv_probe(struct platform_device *pdev)
{
- int err=-ENODEV;
+ int err = -ENODEV;
struct resource *res;
struct pwm_device *pwm;
struct imx_pwm_platform_data *pdata = pdev->dev.platform_data;
- printk(KERN_INFO "Initializing PWM%u...", pdev->id);
-
if (pdev->id >= PWM_MAX_DEV)
- printk(DRIVER_NAME " failed. Unknown PWM%u device. Remember that this device only supports %d PWM\n", pdev->id, PWM_MAX_DEV);
+ dev_err(&pdev->dev, "failed. Unknown module. Remember that this device only supports %d PWM\n", PWM_MAX_DEV);
if (dev_table[pdev->id] != NULL) {
- printk(KERN_ERR ": already used\n");
+ dev_err(&pdev->dev, "already in use\n");
return -ENODEV;
}
if (!pdata) {
- printk(KERN_ERR "Platform data not supplied\n");
+ dev_err(&pdev->dev, "platform data not supplied\n");
return -ENOENT;
}
- if (unlikely((pwm = kmalloc(sizeof(struct pwm_device), GFP_KERNEL)) == NULL)) {
+ pwm = kmalloc(sizeof(struct pwm_device), GFP_KERNEL);
+ if (!pwm) {
return -ENOMEM;
}
- memset(&pwm->class_dev, 0, sizeof(struct device));
- pwm->class_dev.class = &pwm_class;
- pwm->class_dev.parent = &pdev->dev;
- snprintf(pwm->class_dev.bus_id, BUS_ID_SIZE, "pwm%i", pdev->id);
pwm->active = 0;
pwm->duty = 500; /* = 50.O% */
- pdev->dev.driver_data = pwm;
+ pwm->frequency = 0;
+ platform_set_drvdata(pdev, pwm);
dev_table[pdev->id] = pwm;
pwm->irq = platform_get_irq(pdev, 0);
if (pwm->irq < 0) {
- printk(KERN_ERR "No interrupt defined\n");
+ dev_err(&pdev->dev, "no interrupt defined\n");
err = -ENOENT;
goto error_malloc;
}
- if (unlikely(!(res = platform_get_resource(pdev, IORESOURCE_MEM, 0)))) {
- printk(KERN_ERR "Unable to get mem ressource\n");
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "unable to get mem ressource\n");
err = -ENOENT;
goto error_malloc;
}
if (unlikely(!request_mem_region(res->start, res->end - res->start + 1, DRIVER_NAME))) {
- printk(KERN_ERR "Region busy\n");
+ dev_err(&pdev->dev, "mem region busy\n");
err = -EBUSY;
goto error_malloc;
}
- /* TODO: use iomap() */
- pwm->membase = (unsigned long) IO_ADDRESS(res->start);
+ pwm->membase = ioremap(res->start, resource_size(res));
+ if (!pwm->membase) {
+ err = -ENOMEM;
+ goto error_memreg;
+ }
/* Register our char device */
err = register_chrdev(gMajor, DRIVER_NAME, &pwm_fops);
if (err < 0) {
- printk(KERN_ERR "pwm driver: Unable to register driver\n");
- goto error_memreg;
+ dev_err(&pdev->dev, "unable to register char driver\n");
+ goto error_iounmap;
}
/* Dynamic Major allocation */
if (gMajor == 0) {
gMajor = err;
- printk("PWM major number = %d\n", gMajor);
+ dev_dbg(&pdev->dev, "major = %d\n", gMajor);
}
err = request_irq(pwm->irq, pwm_interrupt, IRQF_DISABLED, DRIVER_NAME, pwm);
if (err) {
- printk(KERN_ERR "<1>cannot init major= %d irq=%d\n", gMajor, pwm->irq);
+ dev_err(&pdev->dev, "can't reserve irq=%d\n", pwm->irq);
goto error_chrdev;
}
@@ -1010,24 +916,29 @@ static int imx_pwm_drv_probe(struct platform_device *pdev)
if (pdata->init)
pdata->init();
- /* Create /sys stuf */
- err = device_register(&pwm->class_dev);
- if (unlikely(err)) goto error_irq;
+ /* Create /dev */
+ pwm->dev = device_create(pwm_class, NULL, MKDEV(gMajor, pdev->id), NULL, "pwm%i", pdev->id);
+ if (IS_ERR(pwm->dev)) {
+ err = PTR_ERR(pwm->dev);
+ dev_err(&pdev->dev, "can't create device\n");
+ goto error_platform_init;
+ }
+ dev_set_drvdata(pwm->dev, pwm);
/* Register the attributes */
- err |= device_create_file(&pwm->class_dev, &dev_attr_duty);
- if (unlikely(err)) goto error_register;
- err |= device_create_file(&pwm->class_dev, &dev_attr_period);
+ err |= device_create_file(pwm->dev, &dev_attr_duty);
+ if (unlikely(err)) goto error_dev_create;
+ err |= device_create_file(pwm->dev, &dev_attr_period);
if (unlikely(err)) goto error_file;
- err |= device_create_file(&pwm->class_dev, &dev_attr_frequency);
+ err |= device_create_file(pwm->dev, &dev_attr_frequency);
if (unlikely(err)) goto error_file;
- err |= device_create_file(&pwm->class_dev, &dev_attr_active);
+ err |= device_create_file(pwm->dev, &dev_attr_active);
if (unlikely(err)) goto error_file;
#ifdef CONFIG_ARCH_MX2
pwm->clk = clk_get(&pdev->dev, "pwm_clk");
if (IS_ERR(pwm->clk)) {
- printk(KERN_ERR "probe - cannot get clock\n");
+ dev_err(&pdev->dev, "can't get clock\n");
goto error_file;
}
clk_enable(pwm->clk);
@@ -1035,46 +946,47 @@ static int imx_pwm_drv_probe(struct platform_device *pdev)
/* init PWM hardware module */
init_pwm(pwm);
- printk("i.MX PWM driver v" DRIVER_VERSION "\n");
+ dev_info(&pdev->dev, "initialized\n");
return 0;
error_file:
- printk(KERN_ERR "%s: class /sys file creation failed\n", DRIVER_NAME);
+ dev_err(&pdev->dev, "class /sys file creation failed\n");
unregister_sys_file(pwm);
-error_register:
- device_unregister(&pwm->class_dev);
-error_irq:
+error_dev_create:
+ device_destroy(pwm_class, MKDEV(gMajor, pdev->id));
+error_platform_init:
+ if (pdata->exit)
+ pdata->exit();
free_irq(pwm->irq, pwm);
error_chrdev:
unregister_chrdev(gMajor, DRIVER_NAME);
+error_iounmap:
+ iounmap(pwm->membase);
error_memreg:
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, resource_size(res));
error_malloc:
kfree(pwm);
+
return err;
}
static inline void unregister_sys_file(struct pwm_device *pwm)
{
/* Unregister /sys attributes */
- device_remove_file(&pwm->class_dev, &dev_attr_active);
- device_remove_file(&pwm->class_dev, &dev_attr_period);
- device_remove_file(&pwm->class_dev, &dev_attr_frequency);
- device_remove_file(&pwm->class_dev, &dev_attr_duty);
+ device_remove_file(pwm->dev, &dev_attr_active);
+ device_remove_file(pwm->dev, &dev_attr_period);
+ device_remove_file(pwm->dev, &dev_attr_frequency);
+ device_remove_file(pwm->dev, &dev_attr_duty);
}
-/**
- * imx_pwm_drv_remove - free claimed resources
- * @pdev: platform device to work with
- */
-static int imx_pwm_drv_remove (struct platform_device *pdev)
+static int imx_pwm_drv_remove(struct platform_device *pdev)
{
struct resource *res;
- struct pwm_device *pwm=(struct pwm_device*)pdev->dev.driver_data;
+ struct pwm_device *pwm = (struct pwm_device*)pdev->dev.driver_data;
struct imx_pwm_platform_data *pdata = pdev->dev.platform_data;
unregister_sys_file(pwm);
- device_unregister(&pwm->class_dev);
+ device_destroy(pwm_class, MKDEV(gMajor, pdev->id));
free_irq(pwm->irq, pwm);
unregister_chrdev(gMajor, DRIVER_NAME);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1088,14 +1000,9 @@ static int imx_pwm_drv_remove (struct platform_device *pdev)
}
#ifdef CONFIG_PM
-/**
- * imx_pwm_drv_suspend - power down
- * @dev: platform device to work with
- * @state: state to reach
- */
-static int imx_pwm_drv_suspend (struct platform_device *pdev, pm_message_t state)
+static int imx_pwm_drv_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct pwm_device *pwm=(struct pwm_device*)pdev->dev.driver_data;
+ struct pwm_device *pwm = (struct pwm_device*)pdev->dev.driver_data;
struct imx_pwm_platform_data *pdata = pdev->dev.platform_data;
clk_disable(pwm->clk);
@@ -1106,11 +1013,7 @@ static int imx_pwm_drv_suspend (struct platform_device *pdev, pm_message_t state
return 0;
}
-/**
- * imx_pwm_drv_resume - power up and continue
- * @pdev: platform device to work with
- */
-static int imx_pwm_drv_resume (struct platform_device *pdev)
+static int imx_pwm_drv_resume(struct platform_device *pdev)
{
struct pwm_device *pwm = (struct pwm_device*)pdev->dev.driver_data;
struct imx_pwm_platform_data *pdata = pdev->dev.platform_data;
@@ -1127,16 +1030,7 @@ static int imx_pwm_drv_resume (struct platform_device *pdev)
# define imx_pwm_drv_suspend NULL
# define imx_pwm_drv_resume NULL
-#endif // CONFIG_PM
-
-/**
- * pwm_class_release -
- * @dev:
- */
-static void pwm_class_release(struct device *dev)
-{
- return;
-}
+#endif /* CONFIG_PM */
static struct platform_driver imx_pwm_driver = {
.probe = imx_pwm_drv_probe,
@@ -1148,48 +1042,16 @@ static struct platform_driver imx_pwm_driver = {
},
};
-static struct sysdev_class pwm_sysclass = {
- .name = "pwm",
-};
-
-static struct sys_device pwm_sys_device = {
- .id = 0,
- .cls = &pwm_sysclass,
-};
-
-static struct class pwm_class = {
- .name = "pwm",
- .dev_release = pwm_class_release,
-};
-
-
static int __init imx_pwm_init(void)
{
- int 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;
- }
+ printk("i.MX PWM driver v" DRIVER_VERSION "\n");
- if (unlikely((ret = sysdev_register(&pwm_sys_device)))) {
- printk(KERN_ERR "%s: couldn't register sysdev, exiting\n", DRIVER_NAME);
- goto out_sysdev_register;
+ pwm_class = class_create(THIS_MODULE, "pwm");
+ if (IS_ERR(pwm_class)) {
+ return PTR_ERR(pwm_class);
}
return platform_driver_register(&imx_pwm_driver);
-
-out_sysdev_register:
- sysdev_class_unregister(&pwm_sysclass);
-out_sysdev_class:
- class_unregister(&pwm_class);
-
- return ret;
}
static void __exit imx_pwm_exit(void)
@@ -1197,11 +1059,10 @@ static void __exit imx_pwm_exit(void)
int i;
platform_driver_unregister(&imx_pwm_driver);
- sysdev_unregister(&pwm_sys_device);
- sysdev_class_unregister(&pwm_sysclass);
- class_unregister(&pwm_class);
+ class_destroy(pwm_class);
for (i=0; i<PWM_MAX_DEV; i++)
dev_table[i] = NULL;
+
printk(DRIVER_NAME " successfully unloaded\n");
}
diff --git a/target/linux/modules/pwm/pwm.h b/target/linux/modules/pwm/pwm.h
index 227e219..dbd3e6e 100644
--- a/target/linux/modules/pwm/pwm.h
+++ b/target/linux/modules/pwm/pwm.h
@@ -1,52 +1,52 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Copyright (C) 2002 Freescale Semiconductors HK Ltd
- *
- */
-
-#ifndef PWM_DEF_H
-#define PWM_DEF_H
-
-#include <linux/ioctl.h>
-
-#define PWM_SAMPLING_8KHZ 8000
-#define PWM_SAMPLING_16KHZ 16000
-#define PWM_SAMPLING_32KHZ 32000
-
-#define PWM_DATA_8BIT 8
-#define PWM_DATA_16BIT 16
-
-#define PWM_SWAP_HCTRL ((unsigned long)0x01<<18)
-#define PWM_SWAP_BCTRL ((unsigned long)0x01<<17)
-
-#define PWM_IOC_MAGIC 'p'
-#define PWM_IOC_SFREQ _IO(PWM_IOC_MAGIC, 0)
-#define PWM_IOC_SDATALEN _IO(PWM_IOC_MAGIC, 1)
-#define PWM_IOC_SMODE _IO(PWM_IOC_MAGIC, 2)
-#define PWM_IOC_SSAMPLE _IO(PWM_IOC_MAGIC, 3)
-#define PWM_IOC_SPERIOD _IO(PWM_IOC_MAGIC, 4)
-#define PWM_IOC_STOP _IO(PWM_IOC_MAGIC, 5)
-#define PWM_IOC_SWAPDATA _IO(PWM_IOC_MAGIC, 6)
-
-#define PWM_PLAY_MODE 1
-#define PWM_TONE_MODE 2
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2002 Freescale Semiconductors HK Ltd
+ *
+ */
+
+#ifndef _PWM_DEF_H_
+#define _PWM_DEF_H_
+
+#include <linux/ioctl.h>
+
+#define PWM_SAMPLING_8KHZ 8000
+#define PWM_SAMPLING_16KHZ 16000
+#define PWM_SAMPLING_32KHZ 32000
+
+#define PWM_DATA_8BIT 8
+#define PWM_DATA_16BIT 16
+
+#define PWM_SWAP_HCTRL ((unsigned long)0x01<<18)
+#define PWM_SWAP_BCTRL ((unsigned long)0x01<<17)
+
+#define PWM_IOC_MAGIC 'p'
+#define PWM_IOC_SFREQ _IO(PWM_IOC_MAGIC, 0)
+#define PWM_IOC_SDATALEN _IO(PWM_IOC_MAGIC, 1)
+#define PWM_IOC_SMODE _IO(PWM_IOC_MAGIC, 2)
+#define PWM_IOC_SSAMPLE _IO(PWM_IOC_MAGIC, 3)
+#define PWM_IOC_SPERIOD _IO(PWM_IOC_MAGIC, 4)
+#define PWM_IOC_STOP _IO(PWM_IOC_MAGIC, 5)
+#define PWM_IOC_SWAPDATA _IO(PWM_IOC_MAGIC, 6)
+
+#define PWM_PLAY_MODE 1
+#define PWM_TONE_MODE 2
struct imx_pwm_platform_data {
int (*init)(void);
int (*exit)(void);
};
-
-#endif
+
+#endif /* _PWM_DEF_H_*/
diff --git a/target/linux/modules/pwm/test/test_pwm.sh b/target/linux/modules/pwm/test/test_pwm.sh
new file mode 120000
index 0000000..2775d09
--- /dev/null
+++ b/target/linux/modules/pwm/test/test_pwm.sh
@@ -0,0 +1 @@
+../../../../test/test_pwm.sh
\ No newline at end of file
diff --git a/target/linux/modules/pwm/test/testpwm.sh b/target/linux/modules/pwm/test/testpwm.sh
deleted file mode 100755
index 93baf9f..0000000
--- a/target/linux/modules/pwm/test/testpwm.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-#
-# Script to test your PWM: plug either an oscilloscope or a buzzer on the signal
-# and launch this script
-#
-
-SYS_DIR="/sys/class/pwm/pwm0/"
-PERIOD="1000 2000 3000 4000 5000 6000 7000 8000 9000 10000"
-FREQUENCY="100 200 300 400 500 600"
-DUTY="001 250 333 500 666 750 999"
-
-if [ ! -d "$SYS_DIR" ]; then
- echo "Can't find /sys/ interface"
- exit 1
-fi
-
-echo "Starting PWM test"
-echo 1 > $SYS_DIR/active
-
-#Test frequency setting
-for freq in $FREQUENCY
-do
- echo $freq > $SYS_DIR/frequency
- echo "Setting PWM to $freq Hz"
- sleep 5
-done
-
-#Test period setting
-for period in $PERIOD
-do
- echo $period > $SYS_DIR/period
- echo "Setting PWM to $period us"
- sleep 5
-
-done
-
-#Test duty cycle setting @1kHz -> duty value = positive width signal value
-echo 1000 > $SYS_DIR/frequency
-for duty in $DUTY
-do
- echo $duty > $SYS_DIR/duty
- echo "Setting duty cycle to $duty/1000 "
- sleep 5
-done
-
-echo 0 > $SYS_DIR/active
-echo "End of PWM test"
diff --git a/target/test/test_pwm.sh b/target/test/test_pwm.sh
new file mode 100755
index 0000000..035e3e4
--- /dev/null
+++ b/target/test/test_pwm.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+#
+# Script to test Armadeus Software release
+#
+# Copyright (C) 2010 The Armadeus Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+
+#
+# Script to test your PWM: plug either an oscilloscope or a buzzer on the signal
+# and launch this script
+#
+
+source ./test_helpers.sh
+source ./test_env.sh
+
+SYS_DIR="/sys/class/pwm/pwm0/"
+PERIOD="1000 2000 3000 4000 5000 6000 7000 8000 9000 10000"
+FREQUENCY="100 200 300 400 500 600 700 800"
+DUTY="001 250 333 500 666 750 999"
+SLEEP_TIME=4
+
+
+prepare_test_for_apf9328()
+{
+ ask_user "Please connect your oscilloscope probe to pin 4 of X21 connector (press ENTER when ready)"
+}
+
+prepare_test_for_apf27()
+{
+ ask_user "Please connect your oscilloscope probe to pin 4 of J22 connector (press ENTER when ready)"
+}
+
+test_pwm()
+{
+ show_test_banner "PWM"
+
+ modprobe imx-pwm
+ if [ ! -d "$SYS_DIR" ]; then
+ echo "can't find /sys/ interface"
+ exit_failed
+ fi
+
+ execute_for_target prepare_test_for_apf9328 prepare_test_for_apf27
+
+ ask_user "Press ENTER when ready to check PWM output (frequencies starting at 100Hz)"
+ echo 1 > $SYS_DIR/active
+ # Test frequency setting
+ for freq in $FREQUENCY; do
+ echo $freq > $SYS_DIR/frequency
+ echo "Setting PWM frequency to $freq Hz"
+ sleep $SLEEP_TIME
+ done
+
+ ask_user "Press ENTER when ready to check PWM output (periods)"
+ # Test period setting
+ for period in $PERIOD; do
+ echo $period > $SYS_DIR/period
+ freq=$((1000000/period))
+ echo "Setting PWM period to $period us (-> $freq Hz)"
+ sleep $SLEEP_TIME
+ done
+
+ ask_user "Press ENTER when ready to check PWM output (duty cycle @ 100Hz)"
+ # Test duty cycle setting @ 100Hz -> duty value = positive width signal value
+ echo 100 > $SYS_DIR/frequency
+ for duty in $DUTY; do
+ echo $duty > $SYS_DIR/duty
+ echo "Setting duty cycle to $duty/1000 "
+ sleep $SLEEP_TIME
+ done
+
+ echo 500 > $SYS_DIR/duty
+ echo 0 > $SYS_DIR/active
+ echo "End of PWM test"
+
+ ask_user "Did you get correct signals ? (y/N)"
+ if [ "$response" != "y" ] && [ "$response" != "yes" ]; then
+ exit_failed
+ fi
+
+ echo_test_ok
+ exit 0
+}
+
+test_pwm
+
diff --git a/target/test/test_release.sh b/target/test/test_release.sh
index 9bece6e..5a2d2b4 100755
--- a/target/test/test_release.sh
+++ b/target/test/test_release.sh
@@ -62,6 +62,8 @@ $THIS_DIR/test_fpga.sh
echo
$THIS_DIR/test_gpio.sh
echo
+$THIS_DIR/test_pwm.sh
+echo
$THIS_DIR/media_perf.sh speed
# Following tests needs Internet access:
ask_user "I will now try to configure Internet access. Press ENTER when ready"
hooks/post-receive
--
armadeus
|