Skip to content

Commit

Permalink
pwm: lpss: Add support for multiple PWMs
Browse files Browse the repository at this point in the history
New Intel SoCs such as Broxton will have four PWMs per PCI (or ACPI)
device. Each PWM has 1k of register space allocated from the parent device.
Add support for this.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
  • Loading branch information
Mika Westerberg authored and Thierry Reding committed Nov 6, 2015
1 parent 912b843 commit 4e11f5a
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 21 deletions.
48 changes: 27 additions & 21 deletions drivers/pwm/pwm-lpss.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
#define PWM_LIMIT (0x8000 + PWM_DIVISION_CORRECTION)
#define NSECS_PER_SEC 1000000000UL

/* Size of each PWM register space if multiple */
#define PWM_SIZE 0x400

struct pwm_lpss_chip {
struct pwm_chip chip;
void __iomem *regs;
Expand All @@ -37,13 +40,15 @@ struct pwm_lpss_chip {

/* BayTrail */
const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
.clk_rate = 25000000
.clk_rate = 25000000,
.npwm = 1,
};
EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);

/* Braswell */
const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
.clk_rate = 19200000
.clk_rate = 19200000,
.npwm = 1,
};
EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);

Expand All @@ -52,6 +57,20 @@ static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
return container_of(chip, struct pwm_lpss_chip, chip);
}

static inline u32 pwm_lpss_read(const struct pwm_device *pwm)
{
struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);

return readl(lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
}

static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value)
{
struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);

writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
}

static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns)
{
Expand Down Expand Up @@ -79,38 +98,30 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
duty_ns = 1;
on_time_div = 255 - (255 * duty_ns / period_ns);

ctrl = readl(lpwm->regs + PWM);
ctrl = pwm_lpss_read(pwm);
ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
ctrl |= on_time_div;
/* request PWM to update on next cycle */
ctrl |= PWM_SW_UPDATE;
writel(ctrl, lpwm->regs + PWM);
pwm_lpss_write(pwm, ctrl);

return 0;
}

static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct pwm_lpss_chip *lpwm = to_lpwm(chip);
u32 ctrl;

ctrl = readl(lpwm->regs + PWM);
writel(ctrl | PWM_ENABLE, lpwm->regs + PWM);

pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
return 0;
}

static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct pwm_lpss_chip *lpwm = to_lpwm(chip);
u32 ctrl;

ctrl = readl(lpwm->regs + PWM);
writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);
}

static const struct pwm_ops pwm_lpss_ops = {
.free = pwm_lpss_disable,
.config = pwm_lpss_config,
.enable = pwm_lpss_enable,
.disable = pwm_lpss_disable,
Expand All @@ -135,7 +146,7 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
lpwm->chip.dev = dev;
lpwm->chip.ops = &pwm_lpss_ops;
lpwm->chip.base = -1;
lpwm->chip.npwm = 1;
lpwm->chip.npwm = info->npwm;

ret = pwmchip_add(&lpwm->chip);
if (ret) {
Expand All @@ -149,11 +160,6 @@ EXPORT_SYMBOL_GPL(pwm_lpss_probe);

int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
{
u32 ctrl;

ctrl = readl(lpwm->regs + PWM);
writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);

return pwmchip_remove(&lpwm->chip);
}
EXPORT_SYMBOL_GPL(pwm_lpss_remove);
Expand Down
1 change: 1 addition & 0 deletions drivers/pwm/pwm-lpss.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct pwm_lpss_chip;

struct pwm_lpss_boardinfo {
unsigned long clk_rate;
unsigned int npwm;
};

extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;
Expand Down

0 comments on commit 4e11f5a

Please sign in to comment.