-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathti_ehr_pwm.patch
108 lines (99 loc) · 3.21 KB
/
ti_ehr_pwm.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index af6f162..836592d 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -225,6 +225,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long period_cycles, duty_cycles;
unsigned short ps_divval, tb_divval;
int i, cmp_reg;
+ struct pwm_device *pwm_alter; /* In case period changes */
if (period_ns > NSEC_PER_SEC)
return -ERANGE;
@@ -244,26 +245,41 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
duty_cycles = (unsigned long)c;
}
+
/*
* Period values should be same for multiple PWM channels as IP uses
- * same period register for multiple channels.
+ * same period register for multiple channels. Check if there is any with
+ * a different period.
*/
- for (i = 0; i < NUM_PWM_CHANNEL; i++) {
- if (pc->period_cycles[i] &&
- (pc->period_cycles[i] != period_cycles)) {
- /*
- * Allow channel to reconfigure period if no other
- * channels being configured.
- */
- if (i == pwm->hwpwm)
+ if (pc->period_cycles[pwm->hwpwm] != period_cycles) {
+ for (i = 0; i < NUM_PWM_CHANNEL; i++) {
+ if (pc->period_cycles[i]) {
+ pwm_alter = &chip->pwms[i];
+ if (pwm_alter->duty > period_ns) {
+ dev_err(chip->dev, "Duty is larger than period");
+ return -EINVAL;
+ }
+ }
+ }
+ if (!pc->period_cycles[pwm->hwpwm])
+ pc->period_cycles[pwm->hwpwm] = period_cycles;
+ for (i = 0; i < NUM_PWM_CHANNEL; i++) {
+ if (pc->period_cycles[i])
+ pc->period_cycles[i] = period_cycles;
+ }
+ for (i = 0; i < NUM_PWM_CHANNEL; i++) {
+ if (i == pwm->hwpwm) /* No need to run for itself */
continue;
-
- dev_err(chip->dev, "Period value conflicts with channel %d\n",
- i);
- return -EINVAL;
+ if (pc->period_cycles[i]) {
+ pwm_alter = &chip->pwms[i];
+ if (ehrpwm_pwm_config(chip, pwm_alter, pwm_alter->duty, period_ns)) {
+ dev_err(chip->dev, "Something went seriously wrong");
+ return -EINVAL;
+ }
+ pwm_alter->period = period_ns;
+ }
}
}
-
pc->period_cycles[pwm->hwpwm] = period_cycles;
/* Configure clock prescaler to support Low frequency PWM wave */
diff --git a/drivers/pwm/pwm_test.c b/drivers/pwm/pwm_test.c
index 9c07880..7b50052 100644
--- a/drivers/pwm/pwm_test.c
+++ b/drivers/pwm/pwm_test.c
@@ -41,7 +41,7 @@ static ssize_t pwm_test_show_duty(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pwm_test *pwm_test = dev_get_drvdata(dev);
-
+ pwm_test->duty = pwm_test->pwm->duty;
return sprintf(buf, "%d\n", pwm_test->duty);
}
@@ -65,7 +65,7 @@ static ssize_t pwm_test_store_duty(struct device *dev,
return rc;
}
- pwm_test->duty = duty;
+ pwm_test->duty = pwm_test->pwm->duty;
return count;
}
@@ -74,7 +74,7 @@ static ssize_t pwm_test_show_period(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pwm_test *pwm_test = dev_get_drvdata(dev);
-
+ pwm_test->period = pwm_test->pwm->period;
return sprintf(buf, "%d\n", pwm_test->period);
}
@@ -102,7 +102,7 @@ static ssize_t pwm_test_store_period(struct device *dev,
return rc;
}
- pwm_test->period = period;
+ pwm_test->period = pwm_test->pwm->period;
return count;
}