九鼎创展论坛中文版English
登录 | 立即注册 设为首页收藏本站 切换到宽版
查看: 5032|回复: 2
打印 上一主题 下一主题

4418,linux下pwm使用?

[复制链接]
跳转到指定楼层
楼主
发表于 2015-9-10 18:50:38 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 duwu891229 于 2015-9-11 10:48 编辑

驱动程序misc使用pwm2和pwm3,示例代码如下:

注册pwm


使用pwm


pwm_request, pwm_free, pwm_config, pwm_enable, pwm_disable由下面代码实现
arch\arm\mach-s5p4418\pwm.c
arch\arm\mach-s5p4418\soc\pwm.c


我调用pwm_config(2, 500000, 1000000), 报错nxp_soc_pwm_set_frequency: can't find clock!!!

210板子这个写法是没问题的!!!
这个可能是什么原因?


######
直接使用内核sysfs测试

这样必出错,启动之后依次敲入命令
[root@x4418 ]# echo "1000, 0" > /sys/devices/platform/pwm/pwm.2
[root@x4418 ]# echo "1000, 50" > /sys/devices/platform/pwm/pwm.2
[   31.572000] nxp_soc_pwm_set_frequency: can't find clock!!!

这样不会错,启动之后依次敲入命令
[root@x4418 ]# echo "1000, 50" > /sys/devices/platform/pwm/pwm.2
回复

使用道具 举报

沙发
 楼主| 发表于 2015-9-11 11:43:58 | 只看该作者
解决办法(个人参考)

修改arch\arm\mach-s5p4418\soc\pwm.c如下:
  1. unsigned long nxp_soc_pwm_set_frequency(int ch, unsigned int request, unsigned int duty)
  2. {
  3.         struct pwm_device *pwm = &devs_pwm[ch];
  4.         volatile unsigned long rate, freq, clock = 0;
  5.         volatile unsigned long hz = 0, pwmhz = 0;
  6.         volatile unsigned int tcnt;
  7.         int i, n, end = 0;

  8.         RET_ASSERT_VAL(PWN_CHANNELS > ch, -EINVAL);
  9.         RET_ASSERT_VAL(ch >= 0, -EINVAL);
  10.         RET_ASSERT_VAL(100 >= duty && duty >= 0, -EINVAL);

  11.         if (request > (clk_in_max/DUTY_MIN_VAL)) {
  12.                 pr_err("Invalid request=%u hz over max pwm out %ld hz\n",
  13.                         request, (clk_in_max/DUTY_MIN_VAL));
  14.                 return -EINVAL;
  15.         }
  16.         if (0 == duty) {
  17.                 pwm->compare = 0;
  18.                 pwm->duty=0;
  19.                 pwm->request = request;
  20.                 pwm_set_device(pwm);
  21.                 return request;
  22.         }

  23. /*duwu20150911
  24.         //for suspend -> resume
  25.     if (pwm->request == request) {
  26.         clock = pwm->rate;
  27.         pwmhz = pwm->pwm_hz;
  28.     }

  29.         //change only dutycycle
  30.         if (pwm->request == request && pwm->duty != duty) {
  31.                 clock = pwm->rate;
  32.                 pwmhz = pwm->pwm_hz;
  33.         //set new pwm out
  34.         } else {
  35.                 for (n = 1; !end; n *= 10) {
  36.                         for (i = (n == 1 ? DUTY_MIN_VAL : 1); 10 > i; i++) {
  37.                                 freq = request * i * n;
  38.                                 if (freq > clk_in_max) {
  39.                                         end = 1;
  40.                                         break;
  41.                                 }
  42.                                 rate = clk_round_rate(pwm->clk, freq);
  43.                                 tcnt = rate/request;
  44.                                 hz = rate/tcnt;
  45.                                 if (0 == rate%request) {
  46.                                         clock = rate, pwmhz = hz, end = 1;
  47.                                         break;
  48.                                 }

  49.                                 if (hz && (abs(hz-request) >= abs(pwmhz-request)))
  50.                                         continue;
  51.                                 clock = rate, pwmhz = hz;
  52.                         }
  53.                 }
  54.         }
  55. */

  56.         if (pwm->request == request) {
  57.                 clock = pwm->rate;
  58.                 pwmhz = pwm->pwm_hz;
  59.         }

  60.         if(pwm->request != request || pwm->rate ==0){
  61.                 for (n = 1; !end; n *= 10) {
  62.                         for (i = (n == 1 ? DUTY_MIN_VAL : 1); 10 > i; i++) {
  63.                                 freq = request * i * n;
  64.                                 if (freq > clk_in_max) {
  65.                                         end = 1;
  66.                                         break;
  67.                                 }
  68.                                 rate = clk_round_rate(pwm->clk, freq);
  69.                                 tcnt = rate/request;
  70.                                 hz = rate/tcnt;
  71.                                 if (0 == rate%request) {
  72.                                         clock = rate, pwmhz = hz, end = 1;
  73.                                         break;
  74.                                 }

  75.                                 if (hz && (abs(hz-request) >= abs(pwmhz-request)))
  76.                                         continue;
  77.                                 clock = rate, pwmhz = hz;
  78.                         }
  79.                 }
  80.         }

  81.         if (clock) {
  82.                 pwm->request = request;
  83.                 pwm->rate = clock;
  84.                 pwm->duty = duty;
  85.                 pwm->pwm_hz = pwmhz;
  86.                 pwm->counter = clock/request;
  87.                 pwm->compare = PWM_COMPARE(pwm->counter, duty) ? : 1;
  88.                 pwm_set_device(pwm);
  89.         } else {
  90.         printk("%s: can't find clock!!!\n", __func__);
  91.     }

  92.         return clock ? pwm->pwm_hz : 0;
  93. }
复制代码
回复 支持 反对

使用道具 举报

板凳
发表于 2015-9-11 13:59:52 | 只看该作者
{:soso_e179:}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳市九鼎创展科技官方论坛 ( 粤ICP备11028681号-2  

GMT+8, 2024-5-20 19:55 , Processed in 0.020752 second(s), 19 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表