13
13
#include <linux/err.h>
14
14
#include <linux/gpio.h>
15
15
#include <linux/kernel.h>
16
+ #include <linux/mfd/ingenic-tcu.h>
17
+ #include <linux/mfd/syscon.h>
16
18
#include <linux/module.h>
17
19
#include <linux/of_device.h>
18
20
#include <linux/platform_device.h>
19
21
#include <linux/pwm.h>
20
-
21
- #include <asm/mach-jz4740/timer.h>
22
+ #include <linux/regmap.h>
22
23
23
24
#define NUM_PWM 8
24
25
25
26
struct jz4740_pwm_chip {
26
27
struct pwm_chip chip ;
28
+ struct regmap * map ;
27
29
};
28
30
29
31
static inline struct jz4740_pwm_chip * to_jz4740 (struct pwm_chip * chip )
@@ -76,36 +78,39 @@ static void jz4740_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
76
78
77
79
static int jz4740_pwm_enable (struct pwm_chip * chip , struct pwm_device * pwm )
78
80
{
79
- uint32_t ctrl = jz4740_timer_get_ctrl (pwm -> pwm );
81
+ struct jz4740_pwm_chip * jz = to_jz4740 (chip );
82
+
83
+ /* Enable PWM output */
84
+ regmap_update_bits (jz -> map , TCU_REG_TCSRc (pwm -> hwpwm ),
85
+ TCU_TCSR_PWM_EN , TCU_TCSR_PWM_EN );
80
86
81
- ctrl |= JZ_TIMER_CTRL_PWM_ENABLE ;
82
- jz4740_timer_set_ctrl (pwm -> hwpwm , ctrl );
83
- jz4740_timer_enable (pwm -> hwpwm );
87
+ /* Start counter */
88
+ regmap_write (jz -> map , TCU_REG_TESR , BIT (pwm -> hwpwm ));
84
89
85
90
return 0 ;
86
91
}
87
92
88
93
static void jz4740_pwm_disable (struct pwm_chip * chip , struct pwm_device * pwm )
89
94
{
90
- uint32_t ctrl = jz4740_timer_get_ctrl ( pwm -> hwpwm );
95
+ struct jz4740_pwm_chip * jz = to_jz4740 ( chip );
91
96
92
97
/*
93
98
* Set duty > period. This trick allows the TCU channels in TCU2 mode to
94
99
* properly return to their init level.
95
100
*/
96
- jz4740_timer_set_duty ( pwm -> hwpwm , 0xffff );
97
- jz4740_timer_set_period ( pwm -> hwpwm , 0x0 );
101
+ regmap_write ( jz -> map , TCU_REG_TDHRc ( pwm -> hwpwm ) , 0xffff );
102
+ regmap_write ( jz -> map , TCU_REG_TDFRc ( pwm -> hwpwm ) , 0x0 );
98
103
99
104
/*
100
105
* Disable PWM output.
101
106
* In TCU2 mode (channel 1/2 on JZ4750+), this must be done before the
102
107
* counter is stopped, while in TCU1 mode the order does not matter.
103
108
*/
104
- ctrl &= ~ JZ_TIMER_CTRL_PWM_ENABLE ;
105
- jz4740_timer_set_ctrl ( pwm -> hwpwm , ctrl );
109
+ regmap_update_bits ( jz -> map , TCU_REG_TCSRc ( pwm -> hwpwm ),
110
+ TCU_TCSR_PWM_EN , 0 );
106
111
107
112
/* Stop counter */
108
- jz4740_timer_disable ( pwm -> hwpwm );
113
+ regmap_write ( jz -> map , TCU_REG_TECR , BIT ( pwm -> hwpwm ) );
109
114
}
110
115
111
116
static int jz4740_pwm_apply (struct pwm_chip * chip , struct pwm_device * pwm ,
@@ -115,7 +120,6 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
115
120
unsigned long long tmp = 0xffffull * NSEC_PER_SEC ;
116
121
struct clk * clk = pwm_get_chip_data (pwm );
117
122
unsigned long period , duty ;
118
- uint16_t ctrl ;
119
123
long rate ;
120
124
int err ;
121
125
@@ -163,24 +167,32 @@ static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
163
167
return err ;
164
168
}
165
169
166
- jz4740_timer_set_count (pwm -> hwpwm , 0 );
167
- jz4740_timer_set_duty (pwm -> hwpwm , duty );
168
- jz4740_timer_set_period (pwm -> hwpwm , period );
170
+ /* Reset counter to 0 */
171
+ regmap_write (jz4740 -> map , TCU_REG_TCNTc (pwm -> hwpwm ), 0 );
172
+
173
+ /* Set duty */
174
+ regmap_write (jz4740 -> map , TCU_REG_TDHRc (pwm -> hwpwm ), duty );
169
175
170
- ctrl = jz4740_timer_get_ctrl ( pwm -> hwpwm );
171
- ctrl |= JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN ;
176
+ /* Set period */
177
+ regmap_write ( jz4740 -> map , TCU_REG_TDFRc ( pwm -> hwpwm ), period ) ;
172
178
179
+ /* Set abrupt shutdown */
180
+ regmap_update_bits (jz4740 -> map , TCU_REG_TCSRc (pwm -> hwpwm ),
181
+ TCU_TCSR_PWM_SD , TCU_TCSR_PWM_SD );
182
+
183
+ /* Set polarity */
173
184
switch (state -> polarity ) {
174
185
case PWM_POLARITY_NORMAL :
175
- ctrl &= ~JZ_TIMER_CTRL_PWM_ACTIVE_LOW ;
186
+ regmap_update_bits (jz4740 -> map , TCU_REG_TCSRc (pwm -> hwpwm ),
187
+ TCU_TCSR_PWM_INITL_HIGH , 0 );
176
188
break ;
177
189
case PWM_POLARITY_INVERSED :
178
- ctrl |= JZ_TIMER_CTRL_PWM_ACTIVE_LOW ;
190
+ regmap_update_bits (jz4740 -> map , TCU_REG_TCSRc (pwm -> hwpwm ),
191
+ TCU_TCSR_PWM_INITL_HIGH ,
192
+ TCU_TCSR_PWM_INITL_HIGH );
179
193
break ;
180
194
}
181
195
182
- jz4740_timer_set_ctrl (pwm -> hwpwm , ctrl );
183
-
184
196
if (state -> enabled )
185
197
jz4740_pwm_enable (chip , pwm );
186
198
@@ -196,13 +208,20 @@ static const struct pwm_ops jz4740_pwm_ops = {
196
208
197
209
static int jz4740_pwm_probe (struct platform_device * pdev )
198
210
{
211
+ struct device * dev = & pdev -> dev ;
199
212
struct jz4740_pwm_chip * jz4740 ;
200
213
201
- jz4740 = devm_kzalloc (& pdev -> dev , sizeof (* jz4740 ), GFP_KERNEL );
214
+ jz4740 = devm_kzalloc (dev , sizeof (* jz4740 ), GFP_KERNEL );
202
215
if (!jz4740 )
203
216
return - ENOMEM ;
204
217
205
- jz4740 -> chip .dev = & pdev -> dev ;
218
+ jz4740 -> map = device_node_to_regmap (dev -> parent -> of_node );
219
+ if (IS_ERR (jz4740 -> map )) {
220
+ dev_err (dev , "regmap not found: %ld\n" , PTR_ERR (jz4740 -> map ));
221
+ return PTR_ERR (jz4740 -> map );
222
+ }
223
+
224
+ jz4740 -> chip .dev = dev ;
206
225
jz4740 -> chip .ops = & jz4740_pwm_ops ;
207
226
jz4740 -> chip .npwm = NUM_PWM ;
208
227
jz4740 -> chip .base = -1 ;
0 commit comments