Skip to content

Commit

Permalink
pwm: sti: Remove PWM period table
Browse files Browse the repository at this point in the history
Removes the PWM period table. Instead the prescaler is computed
from the period value passed in the config() function.

Signed-off-by: Ajit Pal Singh <[email protected]>
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Thierry Reding <[email protected]>
  • Loading branch information
Ajit Pal Singh authored and thierryreding committed Aug 8, 2014
1 parent 6ad6b83 commit 3aacd3e
Showing 1 changed file with 16 additions and 48 deletions.
64 changes: 16 additions & 48 deletions drivers/pwm/pwm-sti.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
* (at your option) any later version.
*/

#include <linux/bsearch.h>
#include <linux/clk.h>
#include <linux/math64.h>
#include <linux/mfd/syscon.h>
Expand Down Expand Up @@ -56,7 +55,6 @@ struct sti_pwm_chip {
struct regmap_field *prescale_high;
struct regmap_field *pwm_en;
struct regmap_field *pwm_int_en;
unsigned long *pwm_periods;
struct pwm_chip chip;
struct pwm_device *cur;
unsigned int en_count;
Expand All @@ -77,29 +75,31 @@ static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip)
}

/*
* Calculate the period values supported by the PWM for the
* current clock rate.
* Calculate the prescaler value corresponding to the period.
*/
static void sti_pwm_calc_periods(struct sti_pwm_chip *pc)
static int sti_pwm_get_prescale(struct sti_pwm_chip *pc, unsigned long period,
unsigned int *prescale)
{
struct sti_pwm_compat_data *cdata = pc->cdata;
struct device *dev = pc->dev;
unsigned long val;
int i;
unsigned int ps;

/*
* period_ns = (10^9 * (prescaler + 1) * (MAX_PWM_COUNT + 1)) / CLK_RATE
* prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_count + 1)) - 1
*/
val = NSEC_PER_SEC / pc->clk_rate;
val *= cdata->max_pwm_cnt + 1;

dev_dbg(dev, "possible periods for clkrate[HZ]:%lu\n", pc->clk_rate);

for (i = 0; i <= cdata->max_prescale; i++) {
pc->pwm_periods[i] = val * (i + 1);
dev_dbg(dev, "prescale:%d, period[ns]:%lu\n",
i, pc->pwm_periods[i]);
if (period % val) {
return -EINVAL;
} else {
ps = period / val - 1;
if (ps > cdata->max_prescale)
return -EINVAL;
}
*prescale = ps;

return 0;
}

/* Calculate the number of PWM devices configured with a period. */
Expand All @@ -120,17 +120,6 @@ static unsigned int sti_pwm_count_configured(struct pwm_chip *chip)
return ncfg;
}

static int sti_pwm_cmp_periods(const void *key, const void *elt)
{
unsigned long i = *(unsigned long *)key;
unsigned long j = *(unsigned long *)elt;

if (i < j)
return -1;
else
return i == j ? 0 : 1;
}

/*
* For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles.
* The only way to change the period (apart from changing the PWM input clock)
Expand All @@ -148,7 +137,6 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_device *cur = pc->cur;
struct device *dev = pc->dev;
unsigned int prescale = 0, pwmvalx;
unsigned long *found;
int ret;
unsigned int ncfg;
bool period_same = false;
Expand Down Expand Up @@ -178,21 +166,9 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
return ret;

if (!period_same) {
/*
* Search for matching period value.
* The corresponding index is our prescale value.
*/
found = bsearch(&period_ns, &pc->pwm_periods[0],
cdata->max_prescale + 1,
sizeof(unsigned long),
sti_pwm_cmp_periods);
if (!found) {
dev_err(dev,
"failed to find matching period\n");
ret = -EINVAL;
ret = sti_pwm_get_prescale(pc, period_ns, &prescale);
if (ret)
goto clk_dis;
}
prescale = found - &pc->pwm_periods[0];

ret =
regmap_field_write(pc->prescale_low,
Expand Down Expand Up @@ -373,12 +349,6 @@ static int sti_pwm_probe(struct platform_device *pdev)
if (ret)
return ret;

pc->pwm_periods = devm_kzalloc(dev,
sizeof(unsigned long) * (pc->cdata->max_prescale + 1),
GFP_KERNEL);
if (!pc->pwm_periods)
return -ENOMEM;

pc->clk = of_clk_get_by_name(dev->of_node, "pwm");
if (IS_ERR(pc->clk)) {
dev_err(dev, "failed to get PWM clock\n");
Expand All @@ -397,8 +367,6 @@ static int sti_pwm_probe(struct platform_device *pdev)
return ret;
}

sti_pwm_calc_periods(pc);

pc->chip.dev = dev;
pc->chip.ops = &sti_pwm_ops;
pc->chip.base = -1;
Expand Down

0 comments on commit 3aacd3e

Please sign in to comment.