From: "Chai, Chong Yi" <chong.yi.c...@intel.com>

---
 features/soc/baytrail/baytrail.scc                 |   1 +
 .../pwm-Add-freq_hz-and-duty_percent.patch         | 312 +++++++++++++++++++++
 2 files changed, 313 insertions(+)
 create mode 100644 features/soc/baytrail/pwm-Add-freq_hz-and-duty_percent.patch

diff --git a/features/soc/baytrail/baytrail.scc 
b/features/soc/baytrail/baytrail.scc
index b61a2e7..4b71e0f 100644
--- a/features/soc/baytrail/baytrail.scc
+++ b/features/soc/baytrail/baytrail.scc
@@ -72,3 +72,4 @@ patch 
pinctrl-baytrail-unmap-interrupt-when-free-the-gpio-.patch
 patch pinctrl-baytrail-enable-platform-device-in-the-absen.patch
 patch pinctrl-baytrail-setup-IOAPIC-interrupt-for-GPIO-clu.patch
 patch pinctrl-baytrail-Serialize-GPIO-registers-access-wit.patch
+patch pwm-Add-freq_hz-and-duty_percent.patch
diff --git a/features/soc/baytrail/pwm-Add-freq_hz-and-duty_percent.patch 
b/features/soc/baytrail/pwm-Add-freq_hz-and-duty_percent.patch
new file mode 100644
index 0000000..9e3dc9d
--- /dev/null
+++ b/features/soc/baytrail/pwm-Add-freq_hz-and-duty_percent.patch
@@ -0,0 +1,312 @@
+From 15ff282bedbd1b870aeb12d1e3080fd15eb35fe7 Mon Sep 17 00:00:00 2001
+From: Wan Ahmad Zainie <wan.ahmad.zainie.wan.moha...@intel.com>
+Date: Tue, 16 Jun 2015 11:17:21 +0800
+Subject: [PATCH 118/164] pwm: Add freq_hz and duty_percent
+
+Add new sysfs interface, freq_hz and duty_percent, together with their
+helper functions to the PWM framework. This patch will enable the
+duration to be configured in unit Hertz and the "on" duration to be
+configured as percentage.
+
+Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.moha...@intel.com>
+---
+ drivers/pwm/core.c  |   95 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ drivers/pwm/sysfs.c |   71 ++++++++++++++++++++++++++++++++++++++
+ include/linux/pwm.h |   50 +++++++++++++++++++++++++++
+ 3 files changed, 215 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
+index a804713..c0712ea 100644
+--- a/drivers/pwm/core.c
++++ b/drivers/pwm/core.c
+@@ -32,7 +32,8 @@
+ 
+ #include <dt-bindings/pwm/pwm.h>
+ 
+-#define MAX_PWMS 1024
++#define MAX_PWMS      1024
++#define NSECS_PER_SEC 1000000000UL
+ 
+ static DEFINE_MUTEX(pwm_lookup_lock);
+ static LIST_HEAD(pwm_lookup_list);
+@@ -197,6 +198,98 @@ static void of_pwmchip_remove(struct pwm_chip *chip)
+ }
+ 
+ /**
++  * pwm_freq_hz_to_period() - convert duration unit to ns
++  * @pwm: PWM device
++  * @freq_hz: number of cycles in duration of 1 second (Hertz)
++  *
++  */
++unsigned int pwm_freq_hz_to_period(struct pwm_device *pwm,
++                                 unsigned int freq_hz)
++{
++      unsigned long long period_ns = NSECS_PER_SEC;
++      int remainder;
++
++      if (!freq_hz)
++              return 0;
++
++      remainder = do_div(period_ns, freq_hz);
++      if (remainder && (remainder >= (freq_hz >> 1)))
++              period_ns++;
++
++      return period_ns;
++
++}
++EXPORT_SYMBOL_GPL(pwm_freq_hz_to_period);
++
++/**
++  * pwm_period_to_freq_hz() - convert duration unit to Hertz
++  * @pwm: PWM device
++  * @period_ns: duration (in nanoseconds) of one cycle
++  *
++  */
++unsigned int pwm_period_to_freq_hz(struct pwm_device *pwm,
++                                 unsigned int period_ns)
++{
++      unsigned long long freq_hz = NSECS_PER_SEC;
++      int remainder;
++
++      if (!period_ns)
++              return 0;
++
++      remainder = do_div(freq_hz, period_ns);
++      if (remainder && (remainder >= (period_ns >> 1)))
++              freq_hz++;
++
++      return freq_hz;
++}
++EXPORT_SYMBOL_GPL(pwm_period_to_freq_hz);
++
++/**
++  * pwm_duty_percent_to_duty_cycle() - convert "on" time unit to ns
++  * @pwm: PWM device
++  * @duty_percent: "on" time (in percentage)
++  *
++  */
++unsigned int pwm_duty_percent_to_duty_cycle(struct pwm_device *pwm,
++                                          unsigned int duty_percent)
++{
++      unsigned long long duty_cycle;
++      int remainder;
++
++      duty_cycle = (pwm->period) * duty_percent;
++      remainder = do_div(duty_cycle, 100);
++      if (remainder && (remainder >= 50))
++              duty_cycle++;
++
++      return duty_cycle;
++}
++EXPORT_SYMBOL_GPL(pwm_duty_percent_to_duty_cycle);
++
++/**
++  * pwm_duty_cycle_to_duty_percent() - convert "on" time unit to percentage
++  * @pwm: PWM device
++  * @duty_cycle: "on" time (in nanoseconds)
++  *
++  */
++unsigned int pwm_duty_cycle_to_duty_percent(struct pwm_device *pwm,
++                                          unsigned int duty_cycle)
++{
++      unsigned long long duty_percent;
++      int remainder;
++
++      if (!pwm->period)
++              return 0;
++
++      duty_percent = duty_cycle * 100;
++      remainder = do_div(duty_percent, pwm->period);
++      if (remainder && (remainder >= (pwm->period >> 1)))
++              duty_percent++;
++
++      return duty_percent;
++}
++EXPORT_SYMBOL_GPL(pwm_duty_cycle_to_duty_percent);
++
++/**
+  * pwm_set_chip_data() - set private chip data for a PWM
+  * @pwm: PWM device
+  * @data: pointer to chip-specific data
+diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
+index 4bd0c63..8987720 100644
+--- a/drivers/pwm/sysfs.c
++++ b/drivers/pwm/sysfs.c
+@@ -62,6 +62,10 @@ static ssize_t pwm_period_store(struct device *child,
+               return ret;
+ 
+       ret = pwm_config(pwm, pwm->duty_cycle, val);
++      if (0 == ret) {
++              val = pwm_period_to_freq_hz(pwm, val);
++              pwm_set_freq_hz(pwm, val);
++      }
+ 
+       return ret ? : size;
+ }
+@@ -88,6 +92,10 @@ static ssize_t pwm_duty_cycle_store(struct device *child,
+               return ret;
+ 
+       ret = pwm_config(pwm, val, pwm->period);
++      if (0 == ret) {
++              val = pwm_duty_cycle_to_duty_percent(pwm, val);
++              pwm_set_duty_percent(pwm, val);
++      }
+ 
+       return ret ? : size;
+ }
+@@ -157,16 +165,79 @@ static ssize_t pwm_polarity_store(struct device *child,
+       return ret ? : size;
+ }
+ 
++static ssize_t pwm_freq_hz_show(struct device *child,
++                              struct device_attribute *attr,
++                              char *buf)
++{
++      const struct pwm_device *pwm = child_to_pwm_device(child);
++
++      return sprintf(buf, "%u\n", pwm->freq_hz);
++}
++
++static ssize_t pwm_freq_hz_store(struct device *child,
++                               struct device_attribute *attr,
++                               const char *buf, size_t size)
++{
++      struct pwm_device *pwm = child_to_pwm_device(child);
++      unsigned int val, tmp_val;
++      int ret;
++
++      ret = kstrtouint(buf, 0, &val);
++      if (ret)
++              return ret;
++
++      tmp_val = pwm_freq_hz_to_period(pwm, val);
++      ret = pwm_config(pwm, pwm->duty_cycle, tmp_val);
++      if (0 == ret)
++              pwm_set_freq_hz(pwm, val);
++
++      return ret ? : size;
++}
++
++static ssize_t pwm_duty_percent_show(struct device *child,
++                                   struct device_attribute *attr,
++                                   char *buf)
++{
++      const struct pwm_device *pwm = child_to_pwm_device(child);
++
++      return sprintf(buf, "%u\n", pwm->duty_percent);
++}
++
++static ssize_t pwm_duty_percent_store(struct device *child,
++                                    struct device_attribute *attr,
++                                    const char *buf, size_t size)
++{
++      struct pwm_device *pwm = child_to_pwm_device(child);
++      unsigned int val, tmp_val;
++      int ret;
++
++      ret = kstrtouint(buf, 0, &val);
++      if (ret)
++              return ret;
++
++      tmp_val = pwm_duty_percent_to_duty_cycle(pwm, val);
++      ret = pwm_config(pwm, tmp_val, pwm->period);
++      if (0 == ret)
++              pwm_set_duty_percent(pwm, val);
++
++      return ret ? : size;
++}
++
+ static DEVICE_ATTR(period, 0644, pwm_period_show, pwm_period_store);
+ static DEVICE_ATTR(duty_cycle, 0644, pwm_duty_cycle_show, 
pwm_duty_cycle_store);
+ static DEVICE_ATTR(enable, 0644, pwm_enable_show, pwm_enable_store);
+ static DEVICE_ATTR(polarity, 0644, pwm_polarity_show, pwm_polarity_store);
++static DEVICE_ATTR(freq_hz, 0644, pwm_freq_hz_show, pwm_freq_hz_store);
++static DEVICE_ATTR(duty_percent, 0644, pwm_duty_percent_show,
++                 pwm_duty_percent_store);
+ 
+ static struct attribute *pwm_attrs[] = {
+       &dev_attr_period.attr,
+       &dev_attr_duty_cycle.attr,
+       &dev_attr_enable.attr,
+       &dev_attr_polarity.attr,
++      &dev_attr_freq_hz.attr,
++      &dev_attr_duty_percent.attr,
+       NULL
+ };
+ ATTRIBUTE_GROUPS(pwm);
+diff --git a/include/linux/pwm.h b/include/linux/pwm.h
+index f0feafd..f7d6dbb 100644
+--- a/include/linux/pwm.h
++++ b/include/linux/pwm.h
+@@ -89,6 +89,8 @@ struct pwm_device {
+ 
+       unsigned int            period;         /* in nanoseconds */
+       unsigned int            duty_cycle;     /* in nanoseconds */
++      unsigned int            freq_hz;        /* in Hertz       */
++      unsigned int            duty_percent;   /* in percentage  */
+       enum pwm_polarity       polarity;
+ };
+ 
+@@ -114,11 +116,59 @@ static inline unsigned int pwm_get_duty_cycle(struct 
pwm_device *pwm)
+       return pwm ? pwm->duty_cycle : 0;
+ }
+ 
++static inline void pwm_set_freq_hz(struct pwm_device *pwm,
++                                 unsigned int freq_hz)
++{
++      if (pwm)
++              pwm->freq_hz = freq_hz;
++}
++
++static inline unsigned int pwm_get_freq_hz(struct pwm_device *pwm)
++{
++      return pwm ? pwm->freq_hz : 0;
++}
++
++static inline void pwm_set_duty_percent(struct pwm_device *pwm,
++                                      unsigned int duty_percent)
++{
++      if (pwm)
++              pwm->duty_percent = duty_percent;
++}
++
++static inline unsigned int pwm_get_duty_percent(struct pwm_device *pwm)
++{
++      return pwm ? pwm->duty_percent : 0;
++}
++
+ /*
+  * pwm_set_polarity - configure the polarity of a PWM signal
+  */
+ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
+ 
++/*
++ * pwm_freq_hz_to_period() - convert duration unit to ns
++ */
++unsigned int pwm_freq_hz_to_period(struct pwm_device *pwm,
++                                 unsigned int freq_hz);
++
++/*
++ * pwm_period_to_freq_hz() - convert duration unit to Hertz
++ */
++unsigned int pwm_period_to_freq_hz(struct pwm_device *pwm,
++                                 unsigned int period_ns);
++
++/*
++ * pwm_duty_percent_to_duty_cycle() - convert "on" time unit to ns
++ */
++unsigned int pwm_duty_percent_to_duty_cycle(struct pwm_device *pwm,
++                                          unsigned int duty_percent);
++
++/*
++ * pwm_duty_cycle_to_duty_percent() - convert "on" time unit to percentage
++ */
++unsigned int pwm_duty_cycle_to_duty_percent(struct pwm_device *pwm,
++                                          unsigned int duty_cycle);
++
+ /**
+  * struct pwm_ops - PWM controller operations
+  * @request: optional hook for requesting a PWM
+-- 
+1.7.7.6
+
-- 
1.9.1

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to