|
@@ -12,13 +12,7 @@
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
* GNU General Public License for more details.
|
|
|
- *
|
|
|
- * You should have received a copy of the GNU General Public License
|
|
|
- * along with this program; if not, write to the Free Software
|
|
|
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
- *
|
|
|
*/
|
|
|
-
|
|
|
#include <linux/clk.h>
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/interrupt.h>
|
|
@@ -26,6 +20,7 @@
|
|
|
#include <linux/platform_device.h>
|
|
|
#include <linux/sched.h>
|
|
|
#include <linux/wait.h>
|
|
|
+#include <linux/pwm.h>
|
|
|
|
|
|
#include <media/lirc.h>
|
|
|
#include <media/lirc_dev.h>
|
|
@@ -43,7 +38,7 @@
|
|
|
#define TIMER_MAX_VALUE 0xffffffff
|
|
|
|
|
|
struct lirc_rx51 {
|
|
|
- pwm_omap_dmtimer *pwm_timer;
|
|
|
+ struct pwm_device *pwm;
|
|
|
pwm_omap_dmtimer *pulse_timer;
|
|
|
struct pwm_omap_dmtimer_pdata *dmtimer;
|
|
|
struct device *dev;
|
|
@@ -58,32 +53,28 @@ struct lirc_rx51 {
|
|
|
int wbuf[WBUF_LEN];
|
|
|
int wbuf_index;
|
|
|
unsigned long device_is_open;
|
|
|
- int pwm_timer_num;
|
|
|
};
|
|
|
|
|
|
static void lirc_rx51_on(struct lirc_rx51 *lirc_rx51)
|
|
|
{
|
|
|
- lirc_rx51->dmtimer->set_pwm(lirc_rx51->pwm_timer, 0, 1,
|
|
|
- PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE);
|
|
|
+ pwm_enable(lirc_rx51->pwm);
|
|
|
}
|
|
|
|
|
|
static void lirc_rx51_off(struct lirc_rx51 *lirc_rx51)
|
|
|
{
|
|
|
- lirc_rx51->dmtimer->set_pwm(lirc_rx51->pwm_timer, 0, 1,
|
|
|
- PWM_OMAP_DMTIMER_TRIGGER_NONE);
|
|
|
+ pwm_disable(lirc_rx51->pwm);
|
|
|
}
|
|
|
|
|
|
static int init_timing_params(struct lirc_rx51 *lirc_rx51)
|
|
|
{
|
|
|
- u32 load, match;
|
|
|
-
|
|
|
- load = -(lirc_rx51->fclk_khz * 1000 / lirc_rx51->freq);
|
|
|
- match = -(lirc_rx51->duty_cycle * -load / 100);
|
|
|
- lirc_rx51->dmtimer->set_load(lirc_rx51->pwm_timer, 1, load);
|
|
|
- lirc_rx51->dmtimer->set_match(lirc_rx51->pwm_timer, 1, match);
|
|
|
- lirc_rx51->dmtimer->write_counter(lirc_rx51->pwm_timer, TIMER_MAX_VALUE - 2);
|
|
|
- lirc_rx51->dmtimer->start(lirc_rx51->pwm_timer);
|
|
|
+ struct pwm_device *pwm = lirc_rx51->pwm;
|
|
|
+ int duty, period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, lirc_rx51->freq);
|
|
|
+
|
|
|
+ duty = DIV_ROUND_CLOSEST(lirc_rx51->duty_cycle * period, 100);
|
|
|
lirc_rx51->dmtimer->set_int_enable(lirc_rx51->pulse_timer, 0);
|
|
|
+
|
|
|
+ pwm_config(pwm, duty, period);
|
|
|
+
|
|
|
lirc_rx51->dmtimer->start(lirc_rx51->pulse_timer);
|
|
|
|
|
|
lirc_rx51->match = 0;
|
|
@@ -165,7 +156,7 @@ end:
|
|
|
/* Stop TX here */
|
|
|
lirc_rx51_off(lirc_rx51);
|
|
|
lirc_rx51->wbuf_index = -1;
|
|
|
- lirc_rx51->dmtimer->stop(lirc_rx51->pwm_timer);
|
|
|
+
|
|
|
lirc_rx51->dmtimer->stop(lirc_rx51->pulse_timer);
|
|
|
lirc_rx51->dmtimer->set_int_enable(lirc_rx51->pulse_timer, 0);
|
|
|
wake_up_interruptible(&lirc_rx51->wqueue);
|
|
@@ -176,13 +167,13 @@ end:
|
|
|
static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51)
|
|
|
{
|
|
|
struct clk *clk_fclk;
|
|
|
- int retval, pwm_timer = lirc_rx51->pwm_timer_num;
|
|
|
+ int retval;
|
|
|
|
|
|
- lirc_rx51->pwm_timer = lirc_rx51->dmtimer->request_specific(pwm_timer);
|
|
|
- if (lirc_rx51->pwm_timer == NULL) {
|
|
|
- dev_err(lirc_rx51->dev, ": Error requesting GPT%d timer\n",
|
|
|
- pwm_timer);
|
|
|
- return -EBUSY;
|
|
|
+ lirc_rx51->pwm = pwm_get(lirc_rx51->dev, NULL);
|
|
|
+ if (IS_ERR(lirc_rx51->pwm)) {
|
|
|
+ retval = PTR_ERR(lirc_rx51->pwm);
|
|
|
+ dev_err(lirc_rx51->dev, ": pwm_get failed: %d\n", retval);
|
|
|
+ return retval;
|
|
|
}
|
|
|
|
|
|
lirc_rx51->pulse_timer = lirc_rx51->dmtimer->request();
|
|
@@ -192,15 +183,11 @@ static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51)
|
|
|
goto err1;
|
|
|
}
|
|
|
|
|
|
- lirc_rx51->dmtimer->set_source(lirc_rx51->pwm_timer,
|
|
|
- PWM_OMAP_DMTIMER_SRC_SYS_CLK);
|
|
|
lirc_rx51->dmtimer->set_source(lirc_rx51->pulse_timer,
|
|
|
PWM_OMAP_DMTIMER_SRC_SYS_CLK);
|
|
|
-
|
|
|
- lirc_rx51->dmtimer->enable(lirc_rx51->pwm_timer);
|
|
|
lirc_rx51->dmtimer->enable(lirc_rx51->pulse_timer);
|
|
|
-
|
|
|
- lirc_rx51->irq_num = lirc_rx51->dmtimer->get_irq(lirc_rx51->pulse_timer);
|
|
|
+ lirc_rx51->irq_num =
|
|
|
+ lirc_rx51->dmtimer->get_irq(lirc_rx51->pulse_timer);
|
|
|
retval = request_irq(lirc_rx51->irq_num, lirc_rx51_interrupt_handler,
|
|
|
IRQF_SHARED, "lirc_pulse_timer", lirc_rx51);
|
|
|
if (retval) {
|
|
@@ -208,7 +195,7 @@ static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51)
|
|
|
goto err2;
|
|
|
}
|
|
|
|
|
|
- clk_fclk = lirc_rx51->dmtimer->get_fclk(lirc_rx51->pwm_timer);
|
|
|
+ clk_fclk = lirc_rx51->dmtimer->get_fclk(lirc_rx51->pulse_timer);
|
|
|
lirc_rx51->fclk_khz = clk_get_rate(clk_fclk) / 1000;
|
|
|
|
|
|
return 0;
|
|
@@ -216,7 +203,7 @@ static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51)
|
|
|
err2:
|
|
|
lirc_rx51->dmtimer->free(lirc_rx51->pulse_timer);
|
|
|
err1:
|
|
|
- lirc_rx51->dmtimer->free(lirc_rx51->pwm_timer);
|
|
|
+ pwm_put(lirc_rx51->pwm);
|
|
|
|
|
|
return retval;
|
|
|
}
|
|
@@ -226,11 +213,10 @@ static int lirc_rx51_free_port(struct lirc_rx51 *lirc_rx51)
|
|
|
lirc_rx51->dmtimer->set_int_enable(lirc_rx51->pulse_timer, 0);
|
|
|
free_irq(lirc_rx51->irq_num, lirc_rx51);
|
|
|
lirc_rx51_off(lirc_rx51);
|
|
|
- lirc_rx51->dmtimer->disable(lirc_rx51->pwm_timer);
|
|
|
lirc_rx51->dmtimer->disable(lirc_rx51->pulse_timer);
|
|
|
- lirc_rx51->dmtimer->free(lirc_rx51->pwm_timer);
|
|
|
lirc_rx51->dmtimer->free(lirc_rx51->pulse_timer);
|
|
|
lirc_rx51->wbuf_index = -1;
|
|
|
+ pwm_put(lirc_rx51->pwm);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -387,7 +373,6 @@ static int lirc_rx51_release(struct inode *inode, struct file *file)
|
|
|
}
|
|
|
|
|
|
static struct lirc_rx51 lirc_rx51 = {
|
|
|
- .freq = 38000,
|
|
|
.duty_cycle = 50,
|
|
|
.wbuf_index = -1,
|
|
|
};
|
|
@@ -445,14 +430,34 @@ static int lirc_rx51_resume(struct platform_device *dev)
|
|
|
|
|
|
static int lirc_rx51_probe(struct platform_device *dev)
|
|
|
{
|
|
|
+ struct pwm_device *pwm;
|
|
|
+
|
|
|
lirc_rx51_driver.features = LIRC_RX51_DRIVER_FEATURES;
|
|
|
lirc_rx51.pdata = dev->dev.platform_data;
|
|
|
+
|
|
|
+ if (!lirc_rx51.pdata) {
|
|
|
+ dev_err(&dev->dev, "Platform Data is missing\n");
|
|
|
+ return -ENXIO;
|
|
|
+ }
|
|
|
+
|
|
|
if (!lirc_rx51.pdata->dmtimer) {
|
|
|
dev_err(&dev->dev, "no dmtimer?\n");
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
- lirc_rx51.pwm_timer_num = lirc_rx51.pdata->pwm_timer;
|
|
|
+ pwm = pwm_get(&dev->dev, NULL);
|
|
|
+ if (IS_ERR(pwm)) {
|
|
|
+ int err = PTR_ERR(pwm);
|
|
|
+
|
|
|
+ if (err != -EPROBE_DEFER)
|
|
|
+ dev_err(&dev->dev, "pwm_get failed: %d\n", err);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Use default, in case userspace does not set the carrier */
|
|
|
+ lirc_rx51.freq = DIV_ROUND_CLOSEST(pwm_get_period(pwm), NSEC_PER_SEC);
|
|
|
+ pwm_put(pwm);
|
|
|
+
|
|
|
lirc_rx51.dmtimer = lirc_rx51.pdata->dmtimer;
|
|
|
lirc_rx51.dev = &dev->dev;
|
|
|
lirc_rx51_driver.dev = &dev->dev;
|
|
@@ -464,8 +469,6 @@ static int lirc_rx51_probe(struct platform_device *dev)
|
|
|
lirc_rx51_driver.minor);
|
|
|
return lirc_rx51_driver.minor;
|
|
|
}
|
|
|
- dev_info(lirc_rx51.dev, "registration ok, minor: %d, pwm: %d\n",
|
|
|
- lirc_rx51_driver.minor, lirc_rx51.pwm_timer_num);
|
|
|
|
|
|
return 0;
|
|
|
}
|