ir-rx51: use PWM framework instead of OMAP dmtimer
authorIvaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Wed, 22 Jun 2016 19:22:19 +0000 (22:22 +0300)
committerTony Lindgren <tony@atomide.com>
Thu, 30 Jun 2016 04:54:13 +0000 (21:54 -0700)
Convert driver to use PWM framework instead of calling dmtimer functions
directly for PWM timer. Remove paragraph about writing to the Free Software
Foundation's mailing address while at it.

Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Acked-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/pdata-quirks.c
drivers/media/rc/ir-rx51.c
include/linux/platform_data/media/ir-rx51.h

index 9a7073949d1d0c7cf29e793047250b9d043f2fe7..e487575a86ca64b3650a511d926d9c590784e9f7 100644 (file)
@@ -1242,7 +1242,6 @@ static struct pwm_omap_dmtimer_pdata __maybe_unused pwm_dmtimer_pdata = {
 #if defined(CONFIG_IR_RX51) || defined(CONFIG_IR_RX51_MODULE)
 static struct lirc_rx51_platform_data rx51_lirc_data = {
        .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
-       .pwm_timer = 9, /* Use GPT 9 for CIR */
 #if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
        .dmtimer = &pwm_dmtimer_pdata,
 #endif
index 6571ad95990836d85e25d4ab24ee98ff2b358f69..278bb8f3b77ba4262afe6dcdd3429afe3c76b972 100644 (file)
@@ -491,7 +491,6 @@ static struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = {
 
 static struct lirc_rx51_platform_data __maybe_unused rx51_lirc_data = {
        .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
-       .pwm_timer = 9, /* Use GPT 9 for CIR */
 #if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
        .dmtimer = &pwm_dmtimer_pdata,
 #endif
index da839c3a8c8b753b60f15da61009aa5e0a39332a..5096ef3108d91a853d80dd85bb752ee33bd6079f 100644 (file)
  *  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;
 }
index 3038120ca46e2824650690afe6d44719c78943fc..6acf22d497f7f59046cd55bcb0d0d793e82810a4 100644 (file)
@@ -2,8 +2,6 @@
 #define _LIRC_RX51_H
 
 struct lirc_rx51_platform_data {
-       int pwm_timer;
-
        int(*set_max_mpu_wakeup_lat)(struct device *dev, long t);
        struct pwm_omap_dmtimer_pdata *dmtimer;
 };