cloud39E支持PWM0

来源:互联网 发布:考研app推荐软件 编辑:程序博客网 时间:2024/06/06 10:03

ak3918e_pwm.h:

#ifndef __AK_PWM_H_#define __AK_PWM_H_#include <mach/map.h>#define SHARE_PIN_CFG1_REG(AK_VA_SYSCTRL + 0x00000074)     // SHARE PIN CFG1#define SHARE_PIN_CFG2_REG(AK_VA_SYSCTRL + 0x00000078)     // SHARE PIN CFG2#define SHARE_PIN_CFG3_REG(AK_VA_SYSCTRL + 0x0000007C)     // SHARE PIN CFG3#define SHARE_PIN_CFG4_REG(AK_VA_SYSCTRL + 0x000000DC)     // SHARE PIN CFG4#define PWM_TIMER1_CFG0_REG(AK_VA_SYSCTRL + 0x000000B4)     // PWM TIMER1 CFG0#define PWM_TIMER1_CFG1_REG(AK_VA_SYSCTRL + 0x000000B8)     // PWM TIMER1 CFG1#define PWM_TIMER2_CFG0_REG(AK_VA_SYSCTRL + 0x000000BC)     // PWM TIMER2 CFG0#define PWM_TIMER2_CFG1_REG(AK_VA_SYSCTRL + 0x000000C0)     // PWM TIMER2 CFG1#define PWM_TIMER3_CFG0_REG(AK_VA_SYSCTRL + 0x000000C4)     // PWM TIMER3 CFG0#define PWM_TIMER3_CFG1_REG(AK_VA_SYSCTRL + 0x000000C8)     // PWM TIMER3 CFG1#define PWM_TIMER4_CFG0_REG(AK_VA_SYSCTRL + 0x000000CC)     // PWM TIMER4 CFG0#define PWM_TIMER4_CFG1_REG(AK_VA_SYSCTRL + 0x000000D0)     // PWM TIMER4 CFG1#define PWM_TIMER5_CFG0_REG(AK_VA_SYSCTRL + 0x000000D4)     // PWM TIMER5 CFG0#define PWM_TIMER5_CFG1_REG(AK_VA_SYSCTRL + 0x000000D8)     // PWM TIMER5 CFG1#endif

ak3918e_pwm.c:

#include <linux/module.h>  #include <linux/kernel.h>#include <linux/proc_fs.h>  #include <linux/sched.h> #include <linux/string.h>#include <asm/uaccess.h>  #include <mach/gpio.h>#include "ak3918e_pwm.h"   struct proc_dir_entry  *pwm_file;  //*driver_dir,#define PWM_MAX_DUTY_CYCLE       (100)#define PWM_ENABLE       (1<<28)            //pwm/timer enable#define PWM_WORK_MODE        (0x2<<24)      //work as pwm modeunsigned char guc_clk_pre_div;unsigned long gul_pwm_freq ;unsigned long gul_pwm_duty_cycle;static void Set_PWM_Share_Pin(void){//set pin used  as pwmprintk("set pin used as pwm\n");REG32(SHARE_PIN_CFG3_REG)  |=(1<<1)|(1<<0);      //GPIO[10] pin used as PWM3 function}static int pwm_clk_div(unsigned long div){unsigned long reg_value;unsigned long clk = 12000000/(div+1);if(div>255){printk("!!!!!!!!!!!!!!div error\n");return 0;}printk("set clk is %ld\n", clk);reg_value = REG32(PWM_TIMER3_CFG1_REG);reg_value  = 0;reg_value &= ~(0xff<<16);        // clear clk_pre_div =0 ,in control register of pwm/timer (0x0800,001c)reg_value |= (div<<16);               //set clk_pre_div valueREG32(PWM_TIMER3_CFG1_REG) = reg_value;   // write clk_pre_div in register of pwm/timerreturn 1;}static int clk_div_pwm_set_ex( unsigned char clk_div,unsigned long pwm_freq, unsigned short duty_cycle){    unsigned long freq_div;unsigned long high_level_clk, low_level_clk;unsigned long temp_freq;        temp_freq = 12000000 /(clk_div+1);if ( 6000000 < pwm_freq){printk("pwm freq %ld is not in valid range\n", pwm_freq);return 0;}if (temp_freq % pwm_freq){printk("pwm freq %ld can not divide by asic freq %ld \n", pwm_freq, temp_freq);return 0;}if (duty_cycle > PWM_MAX_DUTY_CYCLE){printk("duty_cycle %d is over PWM_MAX_DUTY_CYCLE 100\n", duty_cycle);return 0;}freq_div = temp_freq / pwm_freq;printk("freq_div = %ld\n",freq_div);high_level_clk = freq_div * duty_cycle / PWM_MAX_DUTY_CYCLE-1;if (high_level_clk > 65535){printk("high_level_clk %ld is out of range 65535\n", high_level_clk);return 0;}low_level_clk  = freq_div * (PWM_MAX_DUTY_CYCLE -duty_cycle) / PWM_MAX_DUTY_CYCLE-1;if (low_level_clk > 65535){printk("low_level_clk %ld is out of range 65535\n", low_level_clk);return 0;}if ((high_level_clk + low_level_clk) * duty_cycle < PWM_MAX_DUTY_CYCLE){printk("pwm freq %ld is not support duty cycle %d\n", pwm_freq, duty_cycle);return 0;}REG32(PWM_TIMER3_CFG0_REG)  = (high_level_clk << 16) | low_level_clk;REG32(PWM_TIMER3_CFG1_REG) |= PWM_ENABLE | PWM_WORK_MODE;return 1;}static void pwm_output_test(unsigned char clk_pre_div,unsigned long pwm_freq ,unsigned long pwm_duty_cycle){printk("[pwm_output_test]clk_pre_div =%d ; pwm_freq = %ld ;  pwm_duty_cycle =%ld \n",clk_pre_div,pwm_freq,pwm_duty_cycle);pwm_clk_div(clk_pre_div );  clk_div_pwm_set_ex(clk_pre_div, pwm_freq, pwm_duty_cycle);}static int proc_read_pwm(char *page, char **start, off_t off, int count, int *eof,                  void *data) {          int len;          len = sprintf(page, "div:0->255; freq:92->6000000 ;cycle:0->100 ;\n"" div= %d  freq= %ld  cycle= %ld \n",guc_clk_pre_div,gul_pwm_freq ,gul_pwm_duty_cycle);         return len;  }     static int proc_write_pwm(struct file *file, const char *buffer, unsigned long count,                  void *data) {       char line[50],tmp[50];int i ;        char *pc_div = NULL; //= (char *)line; char *pc_freq = NULL; char *pc_cycle = NULL; if(copy_from_user(line, buffer, count)){printk("[PWM] get data fail \n");return count;}line[count] = 0;memcpy(tmp,line,50);printk("[PWM]count= %ld ::%s  \n",count,line);/*get div val */pc_div   = strstr(tmp,"div=");pc_div   = pc_div + 4;for(i = 0; pc_div[i] != ';';i++);pc_div[i] = 0;printk("[PWM]pc_div = %s  \n",pc_div);guc_clk_pre_div = simple_strtoul(pc_div, NULL, 10);/*get freq val */memcpy(tmp,line,strlen(line));pc_freq  = strstr(tmp,"freq=");pc_freq  = pc_freq + 5;for(i = 0; pc_freq[i] != ';';i++);pc_freq[i] = 0;printk("[PWM]pc_freq = %s  \n",pc_freq);gul_pwm_freq = simple_strtoul(pc_freq, NULL, 10);/*get cycle val */memcpy(tmp,line,strlen(line));pc_cycle = strstr(tmp,"cycle=");pc_cycle = pc_cycle + 6;for(i = 0; pc_cycle[i] != ';';i++);pc_cycle[i] = 0;printk("[PWM]pc_cycle = %s  \n",pc_cycle);gul_pwm_duty_cycle = simple_strtoul(pc_cycle, NULL, 10);pc_div = pc_freq = pc_cycle = NULL;pwm_output_test(guc_clk_pre_div,gul_pwm_freq,gul_pwm_duty_cycle);        return count;  }     static int __init proc_pwm_init(void) {          //driver_dir = proc_mkdir("driver", NULL);          pwm_file = create_proc_entry("driver/pwm", 0, NULL);          pwm_file->read_proc = proc_read_pwm;          pwm_file->write_proc = proc_write_pwm;  Set_PWM_Share_Pin();        return 0;  }     static void __exit proc_pwm_exit(void) {          remove_proc_entry("driver/pwm", NULL);          //remove_proc_entry("driver", NULL);  }     module_init(proc_pwm_init);  module_exit(proc_pwm_exit);  MODULE_LICENSE("GPL");

makefile:

KERN_DIR = /home/anyka/longjiacheng/e3918e/p2/patch2_full/8ebdall:make -C $(KERN_DIR) M=`pwd` modules clean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.orderobj-m+= ak3918e_pwm.o


0 0
原创粉丝点击