Source
81
81
{
82
82
return (pwm_lpss_read(pwm) & PWM_SW_UPDATE) ? -EBUSY : 0;
83
83
}
84
84
85
85
static void pwm_lpss_prepare(struct pwm_lpss_chip *lpwm, struct pwm_device *pwm,
86
86
int duty_ns, int period_ns)
87
87
{
88
88
unsigned long long on_time_div;
89
89
unsigned long c = lpwm->info->clk_rate, base_unit_range;
90
90
unsigned long long base_unit, freq = NSEC_PER_SEC;
91
-
u32 ctrl;
91
+
u32 orig_ctrl, ctrl;
92
92
93
93
do_div(freq, period_ns);
94
94
95
95
/*
96
96
* The equation is:
97
97
* base_unit = round(base_unit_range * freq / c)
98
98
*/
99
99
base_unit_range = BIT(lpwm->info->base_unit_bits) - 1;
100
100
freq *= base_unit_range;
101
101
102
102
base_unit = DIV_ROUND_CLOSEST_ULL(freq, c);
103
103
104
104
on_time_div = 255ULL * duty_ns;
105
105
do_div(on_time_div, period_ns);
106
106
on_time_div = 255ULL - on_time_div;
107
107
108
-
ctrl = pwm_lpss_read(pwm);
108
+
orig_ctrl = ctrl = pwm_lpss_read(pwm);
109
109
ctrl &= ~PWM_ON_TIME_DIV_MASK;
110
110
ctrl &= ~(base_unit_range << PWM_BASE_UNIT_SHIFT);
111
111
base_unit &= base_unit_range;
112
112
ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT;
113
113
ctrl |= on_time_div;
114
-
pwm_lpss_write(pwm, ctrl);
114
+
115
+
if (orig_ctrl != ctrl) {
116
+
pwm_lpss_write(pwm, ctrl);
117
+
pwm_lpss_write(pwm, ctrl | PWM_SW_UPDATE);
118
+
}
115
119
}
116
120
117
121
static inline void pwm_lpss_cond_enable(struct pwm_device *pwm, bool cond)
118
122
{
119
123
if (cond)
120
124
pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
121
125
}
122
126
123
127
static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
124
128
struct pwm_state *state)
128
132
129
133
if (state->enabled) {
130
134
if (!pwm_is_enabled(pwm)) {
131
135
pm_runtime_get_sync(chip->dev);
132
136
ret = pwm_lpss_is_updating(pwm);
133
137
if (ret) {
134
138
pm_runtime_put(chip->dev);
135
139
return ret;
136
140
}
137
141
pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
138
-
pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
139
142
pwm_lpss_cond_enable(pwm, lpwm->info->bypass == false);
140
143
ret = pwm_lpss_wait_for_update(pwm);
141
144
if (ret) {
142
145
pm_runtime_put(chip->dev);
143
146
return ret;
144
147
}
145
148
pwm_lpss_cond_enable(pwm, lpwm->info->bypass == true);
146
149
} else {
147
150
ret = pwm_lpss_is_updating(pwm);
148
151
if (ret)
149
152
return ret;
150
153
pwm_lpss_prepare(lpwm, pwm, state->duty_cycle, state->period);
151
-
pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_SW_UPDATE);
152
154
return pwm_lpss_wait_for_update(pwm);
153
155
}
154
156
} else if (pwm_is_enabled(pwm)) {
155
157
pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);
156
158
pm_runtime_put(chip->dev);
157
159
}
158
160
159
161
return 0;
160
162
}
161
163