summaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-lpss.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-lpss.c')
-rw-r--r--drivers/pwm/pwm-lpss.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index e9798253a16f..e7392bdfdd18 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -29,6 +29,9 @@
29#define PWM_LIMIT (0x8000 + PWM_DIVISION_CORRECTION) 29#define PWM_LIMIT (0x8000 + PWM_DIVISION_CORRECTION)
30#define NSECS_PER_SEC 1000000000UL 30#define NSECS_PER_SEC 1000000000UL
31 31
32/* Size of each PWM register space if multiple */
33#define PWM_SIZE 0x400
34
32struct pwm_lpss_chip { 35struct pwm_lpss_chip {
33 struct pwm_chip chip; 36 struct pwm_chip chip;
34 void __iomem *regs; 37 void __iomem *regs;
@@ -37,13 +40,15 @@ struct pwm_lpss_chip {
37 40
38/* BayTrail */ 41/* BayTrail */
39const struct pwm_lpss_boardinfo pwm_lpss_byt_info = { 42const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
40 .clk_rate = 25000000 43 .clk_rate = 25000000,
44 .npwm = 1,
41}; 45};
42EXPORT_SYMBOL_GPL(pwm_lpss_byt_info); 46EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
43 47
44/* Braswell */ 48/* Braswell */
45const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = { 49const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
46 .clk_rate = 19200000 50 .clk_rate = 19200000,
51 .npwm = 1,
47}; 52};
48EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info); 53EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
49 54
@@ -52,6 +57,20 @@ static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
52 return container_of(chip, struct pwm_lpss_chip, chip); 57 return container_of(chip, struct pwm_lpss_chip, chip);
53} 58}
54 59
60static inline u32 pwm_lpss_read(const struct pwm_device *pwm)
61{
62 struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
63
64 return readl(lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
65}
66
67static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value)
68{
69 struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
70
71 writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
72}
73
55static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm, 74static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
56 int duty_ns, int period_ns) 75 int duty_ns, int period_ns)
57{ 76{
@@ -79,38 +98,30 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
79 duty_ns = 1; 98 duty_ns = 1;
80 on_time_div = 255 - (255 * duty_ns / period_ns); 99 on_time_div = 255 - (255 * duty_ns / period_ns);
81 100
82 ctrl = readl(lpwm->regs + PWM); 101 ctrl = pwm_lpss_read(pwm);
83 ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK); 102 ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
84 ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT; 103 ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
85 ctrl |= on_time_div; 104 ctrl |= on_time_div;
86 /* request PWM to update on next cycle */ 105 /* request PWM to update on next cycle */
87 ctrl |= PWM_SW_UPDATE; 106 ctrl |= PWM_SW_UPDATE;
88 writel(ctrl, lpwm->regs + PWM); 107 pwm_lpss_write(pwm, ctrl);
89 108
90 return 0; 109 return 0;
91} 110}
92 111
93static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm) 112static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
94{ 113{
95 struct pwm_lpss_chip *lpwm = to_lpwm(chip); 114 pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
96 u32 ctrl;
97
98 ctrl = readl(lpwm->regs + PWM);
99 writel(ctrl | PWM_ENABLE, lpwm->regs + PWM);
100
101 return 0; 115 return 0;
102} 116}
103 117
104static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm) 118static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm)
105{ 119{
106 struct pwm_lpss_chip *lpwm = to_lpwm(chip); 120 pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);
107 u32 ctrl;
108
109 ctrl = readl(lpwm->regs + PWM);
110 writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
111} 121}
112 122
113static const struct pwm_ops pwm_lpss_ops = { 123static const struct pwm_ops pwm_lpss_ops = {
124 .free = pwm_lpss_disable,
114 .config = pwm_lpss_config, 125 .config = pwm_lpss_config,
115 .enable = pwm_lpss_enable, 126 .enable = pwm_lpss_enable,
116 .disable = pwm_lpss_disable, 127 .disable = pwm_lpss_disable,
@@ -135,7 +146,7 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
135 lpwm->chip.dev = dev; 146 lpwm->chip.dev = dev;
136 lpwm->chip.ops = &pwm_lpss_ops; 147 lpwm->chip.ops = &pwm_lpss_ops;
137 lpwm->chip.base = -1; 148 lpwm->chip.base = -1;
138 lpwm->chip.npwm = 1; 149 lpwm->chip.npwm = info->npwm;
139 150
140 ret = pwmchip_add(&lpwm->chip); 151 ret = pwmchip_add(&lpwm->chip);
141 if (ret) { 152 if (ret) {
@@ -149,11 +160,6 @@ EXPORT_SYMBOL_GPL(pwm_lpss_probe);
149 160
150int pwm_lpss_remove(struct pwm_lpss_chip *lpwm) 161int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
151{ 162{
152 u32 ctrl;
153
154 ctrl = readl(lpwm->regs + PWM);
155 writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
156
157 return pwmchip_remove(&lpwm->chip); 163 return pwmchip_remove(&lpwm->chip);
158} 164}
159EXPORT_SYMBOL_GPL(pwm_lpss_remove); 165EXPORT_SYMBOL_GPL(pwm_lpss_remove);