1 /*******************************************************************************
4 * Copyright (c) 2012, Media Teck.inc
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public Licence,
8 * version 2, as publish by the Free Software Foundation.
10 * This program is distributed and in hope it will be useful, but WITHOUT
11 * ANY WARRNTY; without even the implied warranty of MERCHANTABITLITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 ********************************************************************************
17 * Author : Changlei Gao (changlei.gao@mediatek.com)
18 ********************************************************************************
21 #include <linux/kernel.h>
22 #include <generated/autoconf.h>
23 #include <linux/types.h>
24 #include <linux/delay.h>
25 #include <asm/atomic.h>
26 #include <asm/uaccess.h>
29 #include <mach/mt_pwm_hal_pub.h>
30 #include <mach/mt_pwm_hal.h>
31 #include <mach/mt_pwm_prv.h>
45 PWM_DATA_WIDTH
, //PWM3&4 SEND_WAVENUM?
46 PWM_THRESH
, //PWM3&4 DATA_WIDTH
47 PWM_SEND_WAVENUM
, //PWM3&4 THRESH
51 U32 PWM_register
[PWM_NUM
]={
52 (PWM_BASE
+0x0010), //PWM1 REGISTER BASE, 15 registers
53 (PWM_BASE
+0x0050), //PWM2 register base 15 registers
54 (PWM_BASE
+0x0090), //PWM3 register base 15 registers
55 (PWM_BASE
+0x00d0), //PWM4 register base 13 registers
56 (PWM_BASE
+0x0110), //PWM5 register base 13 registers
60 static int pwm_power_id
[] = {
71 //pmic_pad : useless on 6582
73 void mt_pwm_power_on_hal(U32 pwm_no
, BOOL pmic_pad
, unsigned long* power_flag
)
75 if(0 == (*power_flag
)){
76 PWMDBG("enable_clock: main\n");//
77 enable_clock(pwm_power_id
[PWM_CG
], "PWM");
78 set_bit(PWM_CG
, power_flag
);
80 if (!test_bit(pwm_no
, power_flag
)) {
81 PWMDBG("enable_clock: %d\n", pwm_no
);//
84 enable_clock(pwm_power_id
[pwm_no
], "PWM"); //enable clock
86 set_bit(pwm_no
,power_flag
);
87 PWMDBG("enable_clock PWM%d\n", pwm_no
+1);
91 void mt_pwm_power_off_hal(U32 pwm_no
, BOOL pmic_pad
, unsigned long* power_flag
)
93 if (test_bit(pwm_no
, power_flag
)) {
94 PWMDBG("disable_clock: %d\n", pwm_no
);//
97 disable_clock(pwm_power_id
[pwm_no
], "PWM"); //disable clock
99 clear_bit(pwm_no
,power_flag
);
100 PWMDBG("disable_clock PWM%d\n", pwm_no
+1);
102 if(BIT(PWM_CG
) == (*power_flag
)){
103 PWMDBG("disable_clock: main\n");//
104 disable_clock(pwm_power_id
[PWM_CG
], "PWM");
105 clear_bit(PWM_CG
, power_flag
);
108 void mt_pwm_init_power_flag(unsigned long* power_flag
)
111 for(;idx<sizeof(pwm_power_id)/sizeof(pwm_power_id[0]);idx++)
113 if(clock_is_on(pwm_power_id[idx]))
115 set_bit(idx,power_flag);
119 clear_bit(idx, power_flag);
122 printk("mt_pwm_init_power_flag 0x%x\n", *power_flag);*/
124 S32
mt_pwm_sel_pmic_hal(U32 pwm_no
)
126 PWMDBG("mt_pwm_sel_pmic\n");//
130 S32
mt_pwm_sel_ap_hal(U32 pwm_no
)
132 PWMDBG("mt_pwm_sel_ap\n");//
136 void mt_set_pwm_enable_hal(U32 pwm_no
)
138 SETREG32(PWM_ENABLE
, 1 << pwm_no
);
140 void mt_set_pwm_disable_hal(U32 pwm_no
)
142 CLRREG32 ( PWM_ENABLE
, 1 << pwm_no
);
144 void mt_set_pwm_enable_seqmode_hal(void)
146 SETREG32 ( PWM_ENABLE
, 1 << PWM_ENABLE_SEQ_OFFSET
);
148 void mt_set_pwm_disable_seqmode_hal(void)
150 CLRREG32 ( PWM_ENABLE
,1 << PWM_ENABLE_SEQ_OFFSET
);
152 S32
mt_set_pwm_test_sel_hal(U32 val
)
154 if (val
== TEST_SEL_TRUE
)
155 SETREG32 ( PWM_ENABLE
, 1 << PWM_ENABLE_TEST_SEL_OFFSET
);
156 else if ( val
== TEST_SEL_FALSE
)
157 CLRREG32 ( PWM_ENABLE
, 1 << PWM_ENABLE_TEST_SEL_OFFSET
);
162 void mt_set_pwm_clk_hal (U32 pwm_no
, U32 clksrc
, U32 div
)
166 if (clksrc
!= PWM_CLK_OLD_MODE_32K
){
167 printk(KERN_ERR
"********PWM could only select 32K src, otherwise waveform may be affected by SSC!!!************\n");
170 reg_con
= PWM_register
[pwm_no
] + 4* PWM_CON
;
171 MASKREG32 ( reg_con
, PWM_CON_CLKDIV_MASK
, div
);
172 if (clksrc
== CLK_BLOCK
)
173 CLRREG32 ( reg_con
, 1 << PWM_CON_CLKSEL_OFFSET
);
174 else if (clksrc
== CLK_BLOCK_BY_1625_OR_32K
)
175 SETREG32 ( reg_con
, 1 << PWM_CON_CLKSEL_OFFSET
);
177 S32
mt_get_pwm_clk_hal(U32 pwm_no
)
179 S32 clk
, clksrc
, clkdiv
;
180 U32 reg_con
, reg_val
,reg_en
;
182 reg_con
= PWM_register
[pwm_no
] + 4*PWM_CON
;
184 reg_val
= INREG32 (reg_con
);
185 reg_en
= INREG32 (PWM_ENABLE
);
187 if ( ( ( reg_val
& PWM_CON_CLKSEL_MASK
) >> PWM_CON_CLKSEL_OFFSET
) == 1 )
188 if ( ((reg_en
&PWM_CON_OLD_MODE_MASK
) >> PWM_CON_OLD_MODE_OFFSET
) == 1)
190 else clksrc
= BLOCK_CLK
;
192 clksrc
= BLOCK_CLK
/1625;
194 clkdiv
= 2 << ( reg_val
& PWM_CON_CLKDIV_MASK
);
196 PWMDBG ( "clkdiv less zero, not valid \n" );
201 PWMDBG ( "CLK is :%d\n", clk
);
204 S32
mt_set_pwm_con_datasrc_hal ( U32 pwm_no
, U32 val
)
208 reg_con
= PWM_register
[pwm_no
] + 4*PWM_CON
;
209 if ( val
== PWM_FIFO
)
210 CLRREG32 ( reg_con
, 1 << PWM_CON_SRCSEL_OFFSET
);
211 else if ( val
== MEMORY
)
212 SETREG32 ( reg_con
, 1 << PWM_CON_SRCSEL_OFFSET
);
217 S32
mt_set_pwm_con_mode_hal( U32 pwm_no
, U32 val
)
221 reg_con
= PWM_register
[pwm_no
] + 4*PWM_CON
;
223 CLRREG32 ( reg_con
, 1 << PWM_CON_MODE_OFFSET
);
224 else if (val
== RAND
)
225 SETREG32 ( reg_con
, 1 << PWM_CON_MODE_OFFSET
);
230 S32
mt_set_pwm_con_idleval_hal(U32 pwm_no
, U16 val
)
234 reg_con
= PWM_register
[pwm_no
] + 4*PWM_CON
;
235 if ( val
== IDLE_TRUE
)
236 SETREG32 ( reg_con
,1 << PWM_CON_IDLE_VALUE_OFFSET
);
237 else if ( val
== IDLE_FALSE
)
238 CLRREG32 ( reg_con
, 1 << PWM_CON_IDLE_VALUE_OFFSET
);
243 S32
mt_set_pwm_con_guardval_hal(U32 pwm_no
, U16 val
)
247 reg_con
= PWM_register
[pwm_no
] + 4*PWM_CON
;
248 if ( val
== GUARD_TRUE
)
249 SETREG32 ( reg_con
, 1 << PWM_CON_GUARD_VALUE_OFFSET
);
250 else if ( val
== GUARD_FALSE
)
251 CLRREG32 ( reg_con
, 1 << PWM_CON_GUARD_VALUE_OFFSET
);
256 void mt_set_pwm_con_stpbit_hal(U32 pwm_no
, U32 stpbit
, U32 srcsel
)
260 reg_con
= PWM_register
[pwm_no
] + 4*PWM_CON
;
261 if ( srcsel
== PWM_FIFO
)
262 MASKREG32 ( reg_con
, PWM_CON_STOP_BITS_MASK
, stpbit
<< PWM_CON_STOP_BITS_OFFSET
);
263 if ( srcsel
== MEMORY
)
264 MASKREG32 ( reg_con
, PWM_CON_STOP_BITS_MASK
& (0x1f << PWM_CON_STOP_BITS_OFFSET
), stpbit
<< PWM_CON_STOP_BITS_OFFSET
);
266 S32
mt_set_pwm_con_oldmode_hal ( U32 pwm_no
, U32 val
)
270 reg_con
= PWM_register
[pwm_no
] + 4*PWM_CON
;
271 if ( val
== OLDMODE_DISABLE
)
272 CLRREG32 ( reg_con
, 1 << PWM_CON_OLD_MODE_OFFSET
);
273 else if ( val
== OLDMODE_ENABLE
)
274 SETREG32 ( reg_con
, 1 << PWM_CON_OLD_MODE_OFFSET
);
279 void mt_set_pwm_HiDur_hal(U32 pwm_no
, U16 DurVal
)//only low 16 bits are valid
283 reg_HiDur
= PWM_register
[pwm_no
]+4*PWM_HDURATION
;
284 OUTREG32 ( reg_HiDur
, DurVal
);
286 void mt_set_pwm_LowDur_hal (U32 pwm_no
, U16 DurVal
)
289 reg_LowDur
= PWM_register
[pwm_no
] + 4*PWM_LDURATION
;
290 OUTREG32 ( reg_LowDur
, DurVal
);
292 void mt_set_pwm_GuardDur_hal (U32 pwm_no
, U16 DurVal
)
295 reg_GuardDur
= PWM_register
[pwm_no
] + 4*PWM_GDURATION
;
296 OUTREG32 ( reg_GuardDur
, DurVal
);
298 void mt_set_pwm_send_data0_hal ( U32 pwm_no
, U32 data
)
301 reg_data0
= PWM_register
[pwm_no
] + 4 * PWM_SEND_DATA0
;
302 OUTREG32 ( reg_data0
, data
);
304 void mt_set_pwm_send_data1_hal ( U32 pwm_no
, U32 data
)
307 reg_data1
= PWM_register
[pwm_no
] + 4 * PWM_SEND_DATA1
;
308 OUTREG32 ( reg_data1
, data
);
310 void mt_set_pwm_wave_num_hal ( U32 pwm_no
, U16 num
)
313 reg_wave_num
= PWM_register
[pwm_no
] + 4 * PWM_WAVE_NUM
;
314 OUTREG32 ( reg_wave_num
, num
);
316 void mt_set_pwm_data_width_hal ( U32 pwm_no
, U16 width
)
319 if (pwm_no
== PWM5
|| pwm_no
== PWM4
) {
320 reg_data_width
= PWM_register
[pwm_no
] + 4 * PWM_THRESH
;
322 reg_data_width
= PWM_register
[pwm_no
] + 4 * PWM_DATA_WIDTH
;
324 OUTREG32 ( reg_data_width
, width
);
326 void mt_set_pwm_thresh_hal ( U32 pwm_no
, U16 thresh
)
330 if (pwm_no
== PWM5
|| pwm_no
== PWM4
) {
331 reg_thresh
= PWM_register
[pwm_no
] + 4 * PWM_SEND_WAVENUM
;
333 reg_thresh
= PWM_register
[pwm_no
] + 4 * PWM_THRESH
;
335 OUTREG32 ( reg_thresh
, thresh
);
337 S32
mt_get_pwm_send_wavenum_hal ( U32 pwm_no
)
339 U32 reg_send_wavenum
;
342 reg_send_wavenum
= PWM_register
[pwm_no
] + 4 * PWM_SEND_WAVENUM
;
344 reg_send_wavenum
= PWM_register
[pwm_no
] + 4 * (PWM_SEND_WAVENUM
- 2); //pwm4,pwm5,pwm6 has no data width and thresh register
345 return INREG32 ( reg_send_wavenum
);
348 void mt_set_intr_enable_hal(U32 pwm_intr_enable_bit
)
350 SETREG32 ( PWM_INT_ENABLE
, 1 << pwm_intr_enable_bit
);
352 S32
mt_get_intr_status_hal(U32 pwm_intr_status_bit
)
355 ret
= INREG32 ( PWM_INT_STATUS
);
356 ret
= ( ret
>> pwm_intr_status_bit
) & 0x01;
359 void mt_set_intr_ack_hal ( U32 pwm_intr_ack_bit
)
361 SETREG32 ( PWM_INT_ACK
, 1 << pwm_intr_ack_bit
);
364 void mt_pwm_dump_regs_hal(void)
368 reg_val
= INREG32(PWM_ENABLE
);
369 PWMMSG("\r\n[PWM_ENABLE is:%x]\n\r ", reg_val
);
370 printk("<0>""peri pdn0 clock: 0x%x\n", INREG32(PERI_PDN0_STA
));
372 for ( i
= PWM1
; i
< PWM_MAX
; i
++ )
374 reg_val
= INREG32(PWM_register
[i
] + 4* PWM_CON
);
375 PWMMSG("\r\n[PWM%d_CON is:%x]\r\n", i
+1, reg_val
);
376 reg_val
=INREG32(PWM_register
[i
]+4* PWM_HDURATION
);
377 PWMMSG("[PWM%d_HDURATION is:%x]\r\n",i
+1,reg_val
);
378 reg_val
= INREG32(PWM_register
[i
] + 4* PWM_LDURATION
);
379 PWMMSG("[PWM%d_LDURATION is:%x]\r\n", i
+1, reg_val
);
380 reg_val
=INREG32(PWM_register
[i
]+4* PWM_GDURATION
);
381 PWMMSG("[PWM%d_GDURATION is:%x]\r\n",i
+1,reg_val
);
383 reg_val = INREG32(PWM_register[i] + 4* PWM_BUF0_BASE_ADDR);
384 PWMMSG("\r\n[PWM%d_BUF0_BASE_ADDR is:%x]\r\n", i, reg_val);
385 reg_val=INREG32(PWM_register[i]+4* PWM_BUF0_SIZE);
386 PWMMSG("\r\n[PWM%d_BUF0_SIZE is:%x]\r\n",i,reg_val);
387 reg_val = INREG32(PWM_register[i] + 4* PWM_BUF1_BASE_ADDR);
388 PWMMSG("\r\n[PWM%d_BUF1_BASE_ADDR is:%x]\r\n", i, reg_val);
389 reg_val=INREG32(PWM_register[i]+4* PWM_BUF1_SIZE);
390 PWMMSG("\r\n[PWM%d_BUF1_SIZE is:%x]\r\n",i+1,reg_val);
392 reg_val
= INREG32(PWM_register
[i
] + 4* PWM_SEND_DATA0
);
393 PWMMSG("[PWM%d_SEND_DATA0 is:%x]\r\n", i
+1, reg_val
);
394 reg_val
=INREG32(PWM_register
[i
]+4* PWM_SEND_DATA1
);
395 PWMMSG("[PWM%d_PWM_SEND_DATA1 is:%x]\r\n",i
+1,reg_val
);
396 reg_val
= INREG32(PWM_register
[i
] + 4* PWM_WAVE_NUM
);
397 PWMMSG("[PWM%d_WAVE_NUM is:%x]\r\n", i
+1, reg_val
);
398 if(i
==PWM5
||i
==PWM4
){
399 reg_val
=INREG32(PWM_register
[i
]+4* PWM_THRESH
);
401 reg_val
=INREG32(PWM_register
[i
]+4* PWM_DATA_WIDTH
);
403 PWMMSG("[PWM%d_WIDTH is:%x]\r\n",i
+1,reg_val
);
404 if(i
==PWM5
||i
==PWM4
){
405 reg_val
=INREG32(PWM_register
[i
]+4* PWM_SEND_WAVENUM
);
407 reg_val
=INREG32(PWM_register
[i
]+4* PWM_THRESH
);
409 PWMMSG("[PWM%d_THRESH is:%x]\r\n",i
+1,reg_val
);
410 if(i
==PWM5
||i
==PWM4
){
411 reg_val
=INREG32(PWM_register
[i
]+4* PWM_DATA_WIDTH
);
413 reg_val
=INREG32(PWM_register
[i
]+4* PWM_SEND_WAVENUM
);
415 PWMMSG("[PWM%d_SEND_WAVENUM is:%x]\r\n",i
+1,reg_val
);
417 reg_val=INREG32(PWM_register[i]+4* PWM_VALID);
418 PWMMSG("\r\n[PWM%d_SEND_VALID is:%x]\r\n",i+1,reg_val);
422 /*----------------------------*/
423 static void mt_pmic_pwm1_test(void)
425 struct pwm_spec_config conf;
426 printk("<0>""=============mt_pmic_pwm1_test===============\n");
428 mt_set_gpio_mode(GPIO12,GPIO_MODE_02);
430 conf.mode = PWM_MODE_FIFO;
431 conf.clk_div = CLK_DIV1;
432 conf.clk_src = PWM_CLK_NEW_MODE_BLOCK;
434 conf.pmic_pad = false;
435 conf.PWM_MODE_FIFO_REGS.IDLE_VALUE = IDLE_FALSE;
436 conf.PWM_MODE_FIFO_REGS.GUARD_VALUE = GUARD_FALSE;
437 conf.PWM_MODE_FIFO_REGS.STOP_BITPOS_VALUE = 62;
438 conf.PWM_MODE_FIFO_REGS.HDURATION = 0;
439 conf.PWM_MODE_FIFO_REGS.LDURATION = 0;
440 conf.PWM_MODE_FIFO_REGS.GDURATION = 0;
441 conf.PWM_MODE_FIFO_REGS.SEND_DATA0 = 0xf0f0f0f0;
442 conf.PWM_MODE_FIFO_REGS.SEND_DATA1 = 0xf0f0f0f0;
443 conf.PWM_MODE_FIFO_REGS.WAVE_NUM = 0;
444 printk(KERN_INFO "PWM: clk_div = %x, clk_src = %x, pwm_no = %x\n", conf.clk_div, conf.clk_src, conf.pwm_no);
445 pwm_set_spec_config(&conf);
447 mt_set_gpio_mode(GPIO1,GPIO_MODE_01);
449 conf.PWM_MODE_FIFO_REGS.STOP_BITPOS_VALUE = 30;
450 pwm_set_spec_config(&conf);*/
453 static void mt_pmic_pwm6_test(void)
455 //printk("<0>""=================mt_pmic_pwm6_test==================\n");
457 //mt_pwm_disable(PWM1, false);
458 //mt_pwm_disable(PWM7, true);
461 void pwm_debug_store_hal()
464 printk("<0>""peri pdn0 clock: 0x%x\n", INREG32(PERI_PDN0_STA
));
468 void pwm_debug_show_hal()
470 mt_pwm_dump_regs_hal();
474 /*----------3dLCM support-----------*/
476 base pwm2, select pwm3&4&5 same as pwm2 or inversion of pwm2
478 void mt_set_pwm_3dlcm_enable_hal(BOOL enable
)
480 SETREG32 ( PWM_3DLCM
, 1 << PWM_3DLCM_ENABLE_OFFSET
);
484 set "pwm_no" inversion of pwm2 or not,
485 pwm_no: only support PWM3/4/5
487 void mt_set_pwm_3dlcm_inv_hal(U32 pwm_no
, BOOL inv
)
491 SETREG32 ( PWM_3DLCM
, 1 << PWM_3DLCM_0_INV
);
492 }else if (pwm_no
== PWM4
){
493 SETREG32 ( PWM_3DLCM
, 1 << PWM_3DLCM_1_INV
);
494 }else if (pwm_no
== PWM5
){
495 SETREG32 ( PWM_3DLCM
, 1 << PWM_3DLCM_2_INV
);
499 CLRREG32 ( PWM_3DLCM
, 1 << PWM_3DLCM_0_INV
);
500 }else if (pwm_no
== PWM4
){
501 CLRREG32 ( PWM_3DLCM
, 1 << PWM_3DLCM_1_INV
);
502 }else if (pwm_no
== PWM5
){
503 CLRREG32 ( PWM_3DLCM
, 1 << PWM_3DLCM_2_INV
);
508 void mt_set_pwm_3dlcm_base_hal(U32 pwm_no
)
512 void mt_pwm_26M_clk_enable_hal (U32 enable
)