Esempio n. 1
0
static int ehrpwm_hr_duty_config(struct pwm_device *p)
{
	unsigned char no_of_mepsteps;
	unsigned short cmphr_val;
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);

	if (!p->tick_hz) {
		dev_dbg(p->dev, "%s: p->tick_hz is zero\n", __func__);
		return -EINVAL;
	}

	/*
	 * Calculate the no of MEP steps. Assume system clock
	 * is in the order of MHZ.
	 */
	no_of_mepsteps = USEC_PER_SEC / ((p->tick_hz / USEC_PER_SEC) * 63);

	pm_runtime_get_sync(ehrpwm->dev);
	/* Calculate the CMPHR Value */
	cmphr_val = p->tick_hz / USEC_PER_SEC;
	cmphr_val = (p->duty_ns * cmphr_val) % MSEC_PER_SEC;
	cmphr_val = (cmphr_val * no_of_mepsteps) / 1000;
	cmphr_val = (cmphr_val << 8) + 0x180;
	ehrpwm_write(ehrpwm, CMPAHR, cmphr_val);

	if (ehrpwm->version == PWM_VERSION_1)
		ehrpwm_write(ehrpwm, AM335X_HRCNFG, 0x2);
	else
		ehrpwm_write(ehrpwm, HRCNFG, 0x2);

	pm_runtime_put_sync(ehrpwm->dev);
	return 0;
}
Esempio n. 2
0
static int ehrpwm_pwm_set_dty(struct pwm_device *p)
{
	unsigned short duty_ticks = 0;
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
	int ret = 0;
	int chan;

	chan = p - &ehrpwm->pwm[0];

	if (!ehrpwm->prescale_val) {
		dev_dbg(p->dev, "%s: prescale_val is zero\n", __func__);
		return -EINVAL;
	}

	duty_ticks = p->duty_ticks / ehrpwm->prescale_val;
	debug("\n Prescaler value is %d", ehrpwm->prescale_val);
	debug("\n duty ticks is %d", duty_ticks);
	pm_runtime_get_sync(ehrpwm->dev);
	/* High resolution module */
	if (chan && ehrpwm->prescale_val <= 1) {
		ret = ehrpwm_hr_duty_config(p);
		if (ehrpwm->version == PWM_VERSION_1)
			ehrpwm_write(ehrpwm, AM335X_HRCNFG, 0x2);
		else
			ehrpwm_write(ehrpwm, HRCNFG, 0x2);
	}

	ehrpwm_write(ehrpwm, (chan ? CMPB : CMPA), duty_ticks);
	pm_runtime_put_sync(ehrpwm->dev);
	return ret;
}
Esempio n. 3
0
static int ehrpwm_pwm_set_prd(struct pwm_device *p)
{
	unsigned int ps_div_val = 1;
	unsigned int tb_div_val = 0;
	char ret;
	unsigned short val;
	unsigned short period_ticks;
	struct pwm_device *temp;
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
	int chan = 0;
	/*
	 * Since the device has a singe period register, copy the period
	 * value to the other channel also.
	 */
	chan = p - &ehrpwm->pwm[0];
	temp = &ehrpwm->pwm[!chan];
	temp->period_ticks = p->period_ticks;
	temp->period_ns = p->period_ns;
	debug("\n period_ticks is %lu", p->period_ticks);

	if (p->period_ticks > 65535) {
		ret = get_divider_val(p->period_ticks / 65535 + 1, &ps_div_val,
				&tb_div_val);
		if (ret) {
			dev_err(p->dev, "failed to get the divider value");
			return -EINVAL;
		}
	}

	pm_runtime_get_sync(ehrpwm->dev);
	val = ehrpwm_read(ehrpwm, TBCTL);
	val = (val & ~TBCTL_CLKDIV_MASK & ~TBCTL_HSPCLKDIV_MASK) | tb_div_val;
	ehrpwm_write(ehrpwm, TBCTL, val);
	period_ticks = p->period_ticks / ps_div_val;

	if (period_ticks <= 1) {
		dev_err(p->dev, "Required period/frequency cannot be obtained");
		pm_runtime_put_sync(ehrpwm->dev);
		return -EINVAL;
	}
	/*
	 * Program the period register with 1 less than the actual value since
	 * the module generates waveform with period always 1 greater
	 * the programmed value.
	 */
	ehrpwm_write(ehrpwm, TBPRD, (unsigned short)(period_ticks - 1));
	pm_runtime_put_sync(ehrpwm->dev);
	debug("\n period_ticks is %d", period_ticks);
	ehrpwm->prescale_val = ps_div_val;
	debug("\n Prescaler value is %d", ehrpwm->prescale_val);

	return 0;
}
Esempio n. 4
0
int ehrpwm_tz_force_evt(struct pwm_device *p, enum tz_event event)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);

	if (event == TZ_ONE_SHOT_EVENT)
		ehrpwm_write(ehrpwm, TZFRC, 0x4);
	else if (event == TZ_CYCLE_BY_CYCLE)
		ehrpwm_write(ehrpwm, TZFRC, 0x2);
	else
		return -EINVAL;

	return 0;
}
Esempio n. 5
0
static int ehrpwm_pwm_start(struct pwm_device *p)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
	unsigned short val;
	unsigned short read_val1;
	unsigned short read_val2;
	int chan;

	chan = p - &ehrpwm->pwm[0];
	val = ehrpwm_read(ehrpwm, TBCTL);
	val = (val & ~TBCTL_CTRMODE_MASK) | (TBCTL_CTRMOD_CTRUP |
		 TBCTL_FREERUN_FREE << 14);
	ehrpwm_write(ehrpwm, TBCTL, val);
	ehrpwm_tz_set_action(p, chan, 0x3);
	read_val1 = ehrpwm_read(ehrpwm, TZFLG);
	read_val2 = ehrpwm_read(ehrpwm, TZCTL);
	/*
	 * State of the other channel is determined by reading the
	 * TZCTL register. If the other channel is also in running state,
	 * one shot event status is cleared, otherwise one shot action for
	 * this channel is set to "DO NOTHING.
	 */
	read_val2 = read_val2 & (chan ? 0x3 : (0x3 << 2));
	read_val2 = chan ? read_val2 : (read_val2 >> 2);
	if (!(read_val1 & 0x4) || (read_val2 == 0x3))
		ehrpwm_tz_clr_evt_status(p);
	set_bit(FLAG_RUNNING, &p->flags);

	return 0;
}
Esempio n. 6
0
static int ehrpwm_pwm_set_pol(struct pwm_device *p)
{
	unsigned int act_ctrl_reg;
	unsigned int cmp_reg;
	unsigned int ctreqcmp_mask;
	unsigned int ctreqcmp;
	unsigned short val;
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
	int chan;

	chan = p - &ehrpwm->pwm[0];
	if (!chan) {
		act_ctrl_reg = AQCTLA;
		cmp_reg = CMPA;
		ctreqcmp_mask = ACTCTL_CAU_MASK;
		ctreqcmp = 4;
	} else {
		act_ctrl_reg = AQCTLB;
		cmp_reg = CMPB;
		ctreqcmp_mask = ACTCTL_CBU_MASK;
		ctreqcmp = 8;
	}


	pm_runtime_get_sync(ehrpwm->dev);
	val = ((p->active_high ? ACTCTL_CTREQCMP_HIGH : ACTCTL_CTREQCMP_LOW)
		 << ctreqcmp) | (p->active_high ? ACTCTL_CTREQZRO_LOW :
			ACTCTL_CTREQZRO_HIGH);
	ehrpwm_write(ehrpwm, act_ctrl_reg, val);
	pm_runtime_put_sync(ehrpwm->dev);
	return 0;
}
Esempio n. 7
0
void ehrpwm_context_restore(struct ehrpwm_pwm *ehrpwm,
		struct ehrpwm_context *ehrpwm_ctx)
{
	ehrpwm_write(ehrpwm, TBCTL, ehrpwm_ctx->tbctl);
	ehrpwm_write(ehrpwm, TBPRD, ehrpwm_ctx->tbprd);
	if (ehrpwm->version == PWM_VERSION_1)
		ehrpwm_write(ehrpwm, AM335X_HRCNFG, ehrpwm_ctx->hrcfg);
	else
		ehrpwm_write(ehrpwm, HRCNFG, ehrpwm_ctx->hrcfg);
	ehrpwm_write(ehrpwm, AQCTLA, ehrpwm_ctx->aqctla);
	ehrpwm_write(ehrpwm, AQCTLB, ehrpwm_ctx->aqctlb);
	ehrpwm_write(ehrpwm, AQSFRC, ehrpwm_ctx->aqsfrc);
	ehrpwm_write(ehrpwm, AQCSFRC, ehrpwm_ctx->aqcsfrc);
	ehrpwm_write(ehrpwm, CMPA, ehrpwm_ctx->cmpa);
	ehrpwm_write(ehrpwm, CMPB, ehrpwm_ctx->cmpb);
}
Esempio n. 8
0
static int ehrpwm_pwm_start(struct pwm_device *p)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
	unsigned short val;
	int chan;

	/* Trying to start a running PWM, not allowed */
	if (pwm_is_running(p))
		return -EPERM;

	/* For PWM clock should be enabled on start */
	pm_runtime_get_sync(ehrpwm->dev);

	ehrpwm_pwm_set_pol(p);
	chan = p - &ehrpwm->pwm[0];
	val = ehrpwm_read(ehrpwm, TBCTL);
	val = (val & ~TBCTL_CTRMODE_MASK) | (TBCTL_CTRMOD_CTRUP |
		 TBCTL_FREERUN_FREE << 14);
	ehrpwm_write(ehrpwm, TBCTL, val);

	/* Enable PWM channel output */
	ehrpwm_channel_output_enable(p, chan);

	set_bit(FLAG_RUNNING, &p->flags);
	return 0;
}
Esempio n. 9
0
int ehrpwm_tb_set_phase(struct pwm_device *p, unsigned short val)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);

	ehrpwm_write(ehrpwm, TBPHS, val);

	return 0;
}
Esempio n. 10
0
/* High Resolution Module configuration */
inline int ehrpwm_hr_set_phase(struct pwm_device *p, unsigned char val)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);

	ehrpwm_write(ehrpwm, TBPHSHR, val << 8);

	return 0;
}
Esempio n. 11
0
inline int ehrpwm_hr_set_cmpval(struct pwm_device *p, unsigned char val)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);

	ehrpwm_write(ehrpwm, CMPAHR, val << 8);

	return 0;
}
Esempio n. 12
0
inline int ehrpwm_tz_clr_int_status(struct pwm_device *p)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);

	ehrpwm_write(ehrpwm, TZCLR, 0x1);

	return 0;
}
Esempio n. 13
0
inline int ehrpwm_et_clr_int(struct pwm_device *p)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);

	ehrpwm_write(ehrpwm, ETCLR, ENABLE);

	return 0;
}
Esempio n. 14
0
static void ehrpwm_reg_config(struct ehrpwm_pwm *ehrpwm, unsigned int offset,
	       unsigned short val, unsigned short mask)
{
	unsigned short read_val;

	read_val = ehrpwm_read(ehrpwm, offset);
	read_val = read_val & ~mask;
	read_val = read_val | val;
	ehrpwm_write(ehrpwm, offset, read_val);
}
Esempio n. 15
0
inline int ehrpwm_tz_clr_evt_status(struct pwm_device *p)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
	unsigned short ret;

	ret = ehrpwm_read(ehrpwm, TZFLG);
	ehrpwm_write(ehrpwm, TZCLR, ret & ~0x1);

	return 0;
}
Esempio n. 16
0
inline int ehrpwm_reg_write(struct pwm_device *p, unsigned int reg,
	       unsigned short val)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);

	if (reg > HRCNFG)
		return -EINVAL;

	ehrpwm_write(ehrpwm, reg, val);

	return 0;
}
Esempio n. 17
0
static irqreturn_t ehrpwm_trip_zone_irq_handler(int irq, void *data)
{
	struct ehrpwm_pwm *ehrpwm = (struct ehrpwm_pwm *)data;
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&ehrpwm->lock, flags);
	 ret = ehrpwm_read(ehrpwm, TZFLG);
	if (!(ret & 0x1))
		return IRQ_NONE;

	if (ehrpwm->st_tzint.pcallback)
		ret = ehrpwm->st_tzint.pcallback(ehrpwm, ehrpwm->st_tzint.data);

	ret = ehrpwm_read(ehrpwm, TZFLG);
	ehrpwm_write(ehrpwm, TZCLR, ret & ~0x1);
	ehrpwm_write(ehrpwm, TZCLR, 0x1);
	spin_unlock_irqrestore(&ehrpwm->lock, flags);

	return IRQ_HANDLED;
}
Esempio n. 18
0
int ehrpwm_db_set_delay(struct pwm_device *p, unsigned char edge,
		enum config_mask cfgmask, unsigned long delay)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
	unsigned long delay_ticks;
	unsigned char offset = 0;

	if (!ehrpwm)
		return -EINVAL;

	if (edge == RISING_EDGE_DELAY)
		offset = DBRED;
	else if (edge == FALLING_EDGE_DELAY)
		offset = DBFED;
	else
		return -EINVAL;

	if (cfgmask == CONFIG_TICKS) {
		delay = delay / ehrpwm->prescale_val;
		if (delay > 0x3ff)
			return -EINVAL;
		ehrpwm_write(ehrpwm, offset, delay);
	} else if (cfgmask == CONFIG_NS) {
		delay_ticks = pwm_ns_to_ticks(p, delay);
		delay_ticks = delay_ticks / ehrpwm->prescale_val;
		if (delay_ticks > 0x3ff) {
			ehrpwm_db_get_max_delay(p, CONFIG_NS, &delay_ticks);
			dev_dbg(p->dev, "%s: Expected delay cannot be"
			" attained setting the maximum possible delay of"
			" %lu ns", __func__, delay_ticks);
			delay_ticks = 0x3ff;
		}
		debug("\n delay ticks is %lu", delay_ticks);
		ehrpwm_write(ehrpwm, offset, delay_ticks);
	} else {
		return -EINVAL;
	}

	return 0;
}
Esempio n. 19
0
inline int ehrpwm_reg_write(struct pwm_device *p, unsigned int reg,
	       unsigned short val)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);

	if (!(ehrpwm->version == PWM_VERSION_1)) {
		if (reg > HRCNFG)
			return -EINVAL;
	}

	ehrpwm_write(ehrpwm, reg, val);

	return 0;
}
Esempio n. 20
0
static irqreturn_t ehrpwm_event_irq_handler(int irq, void *data)
{
	struct ehrpwm_pwm *ehrpwm = (struct ehrpwm_pwm *)data;
	unsigned long flags;

	spin_lock_irqsave(&ehrpwm->lock, flags);

	if (ehrpwm->st_etint.pcallback)
		ehrpwm->st_etint.pcallback(ehrpwm, ehrpwm->st_etint.data);

	ehrpwm_write(ehrpwm, ETCLR, 0x1);

	spin_unlock_irqrestore(&ehrpwm->lock, flags);

	return IRQ_HANDLED;
}
Esempio n. 21
0
int ehrpwm_cmp_set_cmp_val(struct pwm_device *p, unsigned char reg,
	unsigned short val)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
	unsigned char offset;

	if (reg > 0x1)
		return -EINVAL;

	if (reg == 0)
		offset = CMPA;
	else
		offset = CMPB;

	ehrpwm_write(ehrpwm, offset, val);

	return 0;
}
Esempio n. 22
0
void 
output_pwm_dir (bbmc_output_motor_t volatile *data)
{
    if (data->output >= 0)
    {
        output_gpio_dir(data->dev_id, GPIO_PIN_HIGH);
    }
    
    if (data->output < 0)
    {
        data->output = -1 * data->output;
        output_gpio_dir(data->dev_id, GPIO_PIN_LOW);
    }
    
    if (data->output > 100)
    {
        data->output = 100;
    }
    
    ehrpwm_write(data->dev_id, EHRPWM_WRITE_A, data->output);
}
Esempio n. 23
0
void 
output_pwm_dif (bbmc_output_motor_t volatile *data)
{
    ehrpwm_write(data->dev_id, EHRPWM_WRITE_DIFF, data->output);
}