diff --git a/drivers/amlogic/pwm/pwm-ctrl.c b/drivers/amlogic/pwm/pwm-ctrl.c index 7c4ad5367e0c..a2e25752678b 100644 --- a/drivers/amlogic/pwm/pwm-ctrl.c +++ b/drivers/amlogic/pwm/pwm-ctrl.c @@ -28,6 +28,10 @@ struct pwm_ctrl { int duty0,duty1; }; +#define FREQ_MIN 10 // 10Hz +#define FREQ_MAX 1000000 // 1MHz +#define DUTY_MAX 1024 // Duty cycle Max + //[*]------------------------------------------------------------------------------------------------------------------ // // driver sysfs attribute define @@ -43,15 +47,15 @@ static ssize_t set_enable0 (struct device *dev, struct device_attribute *attr, c mutex_lock(&ctrl->mutex); if(val) { - ctrl->pwm0_status = 1; pwm_disable(ctrl->pwm0); pwm_config(ctrl->pwm0, ctrl->duty0, ctrl->freq0); pwm_enable(ctrl->pwm0); + ctrl->pwm0_status = 1; } else { + ctrl->pwm0_status = 0; pwm_disable(ctrl->pwm0); pwm_config(ctrl->pwm0, 0, ctrl->freq0); - ctrl->pwm0_status = 0; } mutex_unlock(&ctrl->mutex); @@ -75,24 +79,22 @@ static ssize_t set_duty0 (struct device *dev, struct device_attribute *attr, con if(!(sscanf(buf, "%u\n", &val))) return -EINVAL; - if((val > 100)||(val < 0)){ + if((val > DUTY_MAX)||(val < 0)){ dev_err(dev, "PWM_0 : Invalid param. Duty cycle range is 0 to 100 \n"); return count; } - dev_info(dev, "PWM_0 : %s [%d] \n",__FUNCTION__,val); - - mutex_lock(&ctrl->mutex); ctrl->duty0 = val; + mutex_lock(&ctrl->mutex); if(ctrl->pwm0_status){ pwm_disable(ctrl->pwm0); pwm_config(ctrl->pwm0, ctrl->duty0, ctrl->freq0); pwm_enable(ctrl->pwm0); } else { - pwm_disable(ctrl->pwm0); pwm_config(ctrl->pwm0, 0, ctrl->freq0); + pwm_disable(ctrl->pwm0); } mutex_unlock(&ctrl->mutex); @@ -115,24 +117,22 @@ static ssize_t set_freq0 (struct device *dev, struct device_attribute *attr, con if(!(sscanf(buf, "%u\n", &val))) return -EINVAL; - if((val < 0)){ - dev_err(dev, "PWM_0 : Invalid param. Duty cycle range is 0 to 100 \n"); + if((val < FREQ_MIN)||(val > FREQ_MAX)){ + dev_err(dev, "PWM_0 : Invalid param. Frequency range is 10Hz to 1MHz \n"); return count; } - dev_info(dev, "PWM_0 : %s [%d] \n",__FUNCTION__,val); - - mutex_lock(&ctrl->mutex); ctrl->freq0 = val; + mutex_lock(&ctrl->mutex); if(ctrl->pwm0_status){ pwm_disable(ctrl->pwm0); pwm_config(ctrl->pwm0, ctrl->duty0, ctrl->freq0); pwm_enable(ctrl->pwm0); } else { - pwm_disable(ctrl->pwm0); pwm_config(ctrl->pwm0, 0, ctrl->freq0); + pwm_disable(ctrl->pwm0); } mutex_unlock(&ctrl->mutex); @@ -176,13 +176,12 @@ static ssize_t set_enable1 (struct device *dev, struct device_attribute *attr, c mutex_lock(&ctrl->mutex); if(val) { ctrl->pwm1_status = 1; - pwm_disable(ctrl->pwm1); pwm_config(ctrl->pwm1, ctrl->duty1, ctrl->freq1); pwm_enable(ctrl->pwm1); } else { - pwm_disable(ctrl->pwm1); pwm_config(ctrl->pwm1, 0, ctrl->freq1); + pwm_disable(ctrl->pwm1); ctrl->pwm1_status = 0; } mutex_unlock(&ctrl->mutex); @@ -207,23 +206,22 @@ static ssize_t set_duty1 (struct device *dev, struct device_attribute *attr, con if(!(sscanf(buf, "%u\n", &val))) return -EINVAL; - if((val > 100)||(val < 0)){ + if((val > DUTY_MAX)||(val < 0)){ dev_err(dev, "PWM_1 : Invalid param. Duty cycle range is 0 to 100 \n"); return count; } dev_info(dev, "PWM_1 : %s [%d] \n",__FUNCTION__,val); - - mutex_lock(&ctrl->mutex); ctrl->duty1 = val; + mutex_lock(&ctrl->mutex); if(ctrl->pwm1_status){ pwm_disable(ctrl->pwm1); pwm_config(ctrl->pwm1, ctrl->duty1, ctrl->freq1); pwm_enable(ctrl->pwm1); } else { - pwm_disable(ctrl->pwm1); pwm_config(ctrl->pwm1, 0, ctrl->freq1); + pwm_disable(ctrl->pwm1); } mutex_unlock(&ctrl->mutex); @@ -246,22 +244,22 @@ static ssize_t set_freq1 (struct device *dev, struct device_attribute *attr, con if(!(sscanf(buf, "%u\n", &val))) return -EINVAL; - if((val < 10)||(val > 1000000)){ - dev_err(dev, "PWM_1 : Invalid param. Duty cycle range is 10 to 1MHz \n"); + if((val < FREQ_MIN)||(val > FREQ_MAX)){ + dev_err(dev, "PWM_1 : Invalid param. Frequency range is 10Hz to 1MHz \n"); return count; } dev_info(dev, "PWM_1 : %s [%d] \n",__FUNCTION__,val); - mutex_lock(&ctrl->mutex); ctrl->freq1 = val; + mutex_lock(&ctrl->mutex); if(ctrl->pwm1_status){ pwm_disable(ctrl->pwm1); pwm_config(ctrl->pwm1, ctrl->duty1, ctrl->freq1); pwm_enable(ctrl->pwm1); } else { - pwm_disable(ctrl->pwm1); pwm_config(ctrl->pwm1, 0, ctrl->freq1); + pwm_disable(ctrl->pwm1); } mutex_unlock(&ctrl->mutex); diff --git a/drivers/amlogic/pwm/pwm-meson.c b/drivers/amlogic/pwm/pwm-meson.c index 6838fc9a0206..d39f2726eb63 100644 --- a/drivers/amlogic/pwm/pwm-meson.c +++ b/drivers/amlogic/pwm/pwm-meson.c @@ -35,6 +35,7 @@ MODULE_PARM_DESC(npwm,"\n odroid-c1 The number of available pwm (max 2-port)\n") #define PWM_B 0 #define PWM_E 1 #define FIN_FREQ (24 * 1000) +#define DUTY_MAX 1024 struct meson_pwm_device { unsigned int freq; @@ -55,17 +56,12 @@ struct meson_chip { static void meson_pwm_init(struct device *dev, int pwmn) { - unsigned long flags; if(pwmn == 1) { - local_irq_save(flags); aml_write_reg32(P_PWM_MISC_REG_AB, (aml_read_reg32(P_PWM_MISC_REG_AB) & ~(0x7f << 16)) | ((1 << 23))); - local_irq_restore(flags); } else { - local_irq_save(flags); aml_write_reg32(P_PWM_MISC_REG_AB, (aml_read_reg32(P_PWM_MISC_REG_AB) & ~(0x7f << 16)) | ((1 << 23))); aml_write_reg32(P_PWM_MISC_REG_EF, (aml_read_reg32(P_PWM_MISC_REG_EF) & ~(0x7f << 8)) | ((1 << 15))); - local_irq_restore(flags); } return; } @@ -75,10 +71,8 @@ static int meson_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) struct meson_chip *meson = to_meson_chip(chip); struct meson_pwm_device *meson_pwm; unsigned int id = pwm->pwm; - unsigned long flags; meson_pwm = meson->meson_pwm[id]; - local_irq_save(flags); switch (id) { case PWM_B: aml_set_reg32_bits(P_PWM_MISC_REG_AB, 1, 1, 1); //enable pwm_b @@ -87,7 +81,6 @@ static int meson_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) aml_set_reg32_bits(P_PWM_MISC_REG_EF, 1, 0, 1); //enable pwm_e break; } - local_irq_restore(flags); return 0; } @@ -97,10 +90,8 @@ static void meson_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) struct meson_chip *meson = to_meson_chip(chip); struct meson_pwm_device *meson_pwm; unsigned int id = pwm->pwm; - unsigned long flags; meson_pwm = meson->meson_pwm[id]; - local_irq_save(flags); switch (id) { case PWM_B: aml_set_reg32_bits(P_PWM_MISC_REG_AB, 0, 1, 1); //disable pwm_b @@ -109,12 +100,11 @@ static void meson_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) aml_set_reg32_bits(P_PWM_MISC_REG_EF, 0, 0, 1); //disable pwm_e break; } - local_irq_restore(flags); return; } static int meson_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - int duty_percent, int pwm_freq) + int duty, int pwm_freq) { struct meson_chip *meson = to_meson_chip(chip); struct meson_pwm_device *meson_pwm; @@ -122,11 +112,11 @@ static int meson_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, struct device *dev = chip->dev; unsigned pwm_hi = 0, pwm_lo = 0; unsigned fout_freq=0, pwm_cnt, pwm_pre_div; - unsigned long flags=0; + unsigned long temp=0; int i=0; - if((duty_percent<0)||(duty_percent>100)){ - dev_err(dev, "Not available duty_percent... error!!!\n"); + if((duty<0)||(duty>DUTY_MAX)){ + dev_err(dev, "Not available duty... error!!!\n"); return -EINVAL; } meson_pwm = meson->meson_pwm[id]; @@ -138,21 +128,24 @@ static int meson_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, if (pwm_cnt <= 0xffff) break; } - if(duty_percent==0) { + + if(duty==0) { pwm_hi=0; pwm_lo=pwm_cnt; goto div_set; } - if(duty_percent==100) { + else if(duty==DUTY_MAX) { pwm_hi=pwm_cnt; pwm_lo=0; goto div_set; } - pwm_hi = (pwm_cnt*duty_percent)/100; - pwm_lo = (pwm_cnt*(100-duty_percent))/100; + + temp = pwm_cnt*duty; + temp /= DUTY_MAX; + pwm_hi = (unsigned)temp; + pwm_lo = pwm_cnt - pwm_hi; div_set : - local_irq_save(flags); switch(id){ case PWM_B: aml_set_reg32_bits(P_PWM_MISC_REG_AB, pwm_pre_div, 16, 7); //pwm_b_clk_div @@ -165,7 +158,6 @@ div_set : default: break; } - local_irq_restore(flags); return 0; } diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 32221cb0cbe7..59b881346918 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -402,9 +402,13 @@ EXPORT_SYMBOL_GPL(pwm_free); */ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) { +#if !defined(CONFIG_MACH_MESON8B_ODROIDC) if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns) return -EINVAL; - +#else + if (!pwm || duty_ns < 0 || period_ns <= 0) + return -EINVAL; +#endif return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns); } EXPORT_SYMBOL_GPL(pwm_config);