void ev3_output_port_unregister(struct lego_port_device *port)
{
	struct ev3_output_port_data *data;

	/* port can be null if disabled via module parameter */
	if (!port)
		return;

	data = container_of(port, struct ev3_output_port_data, out_port);
	pwm_disable(data->pwm);
	pwm_put(data->pwm);
	hrtimer_cancel(&data->timer);
	cancel_work_sync(&data->change_uevent_work);
	cancel_work_sync(&data->work);
	if (data->motor)
		ev3_output_port_unregister_motor(&data->work);
	if (port->mode == EV3_OUTPUT_PORT_MODE_RAW)
		ev3_output_port_disable_raw_mode(data);
	lego_port_unregister(&data->out_port);
	ev3_output_port_float(data);
	gpio_free_array(data->gpio, ARRAY_SIZE(data->gpio));
	put_legoev3_analog(data->analog);
	dev_set_drvdata(&port->dev, NULL);
	kfree(data);
}
static int sicilia_pwm_power_off(struct pwm_device **dev)
{
	pwm_disable(*dev);
	pwm_put(*dev);
	*dev = NULL;

	return 0;
}
struct lego_port_device
*ev3_output_port_register(struct ev3_output_port_platform_data *pdata,
			  struct device *parent)
{
	struct ev3_output_port_data *data;
	struct pwm_device *pwm;
	int err;

	if (WARN(!pdata, "Platform data is required."))
		return ERR_PTR(-EINVAL);

	data = kzalloc(sizeof(struct ev3_output_port_data), GFP_KERNEL);
	if (!data)
		return ERR_PTR(-ENOMEM);

	data->id = pdata->id;
	data->analog = get_legoev3_analog();
	if (IS_ERR(data->analog)) {
		dev_err(parent, "Could not get legoev3-analog device.\n");
		err = PTR_ERR(data->analog);
		goto err_request_legoev3_analog;
	}

	data->gpio[GPIO_PIN1].gpio	= pdata->pin1_gpio;
	data->gpio[GPIO_PIN1].flags	= GPIOF_IN;
	data->gpio[GPIO_PIN1].label	= "pin1";

	data->gpio[GPIO_PIN2].gpio	= pdata->pin2_gpio;
	data->gpio[GPIO_PIN2].flags	= GPIOF_IN;
	data->gpio[GPIO_PIN2].label	= "pin2";

	data->gpio[GPIO_PIN5].gpio	= pdata->pin5_gpio;
	data->gpio[GPIO_PIN5].flags	= GPIOF_IN;
	data->gpio[GPIO_PIN5].label	= "pin5";

	data->gpio[GPIO_PIN5_INT].gpio	= pdata->pin5_int_gpio;
	data->gpio[GPIO_PIN5_INT].flags	= GPIOF_IN;
	data->gpio[GPIO_PIN5_INT].label	= "pin5_tacho";

	data->gpio[GPIO_PIN6_DIR].gpio	= pdata->pin6_dir_gpio;
	data->gpio[GPIO_PIN6_DIR].flags	= GPIOF_IN;
	data->gpio[GPIO_PIN6_DIR].label	= "pin6";

	err = gpio_request_array(data->gpio, ARRAY_SIZE(data->gpio));
	if (err) {
		dev_err(parent, "Requesting GPIOs failed.\n");
		goto err_gpio_request_array;
	}

	data->out_port.name = ev3_output_port_type.name;
	snprintf(data->out_port.port_name, LEGO_PORT_NAME_SIZE, "out%c",
		 data->id + 'A');
	pwm = pwm_get(NULL, data->out_port.port_name);
	if (IS_ERR(pwm)) {
		dev_err(parent, "Could not get pwm! (%ld)\n", PTR_ERR(pwm));
		err = PTR_ERR(pwm);
		goto err_pwm_get;
	}

	err = pwm_config(pwm, 0, NSEC_PER_SEC / 10000);
	if (err) {
		dev_err(parent,
			"Failed to set pwm duty percent and frequency! (%d)\n",
			err);
		goto err_pwm_config;
	}

	err = pwm_enable(pwm);
	if (err) {
		dev_err(parent, "Failed to start pwm! (%d)\n", err);
		goto err_pwm_start;
	}
	/* This lets us set the pwm duty cycle in an atomic context */
	pm_runtime_irq_safe(pwm->chip->dev);
	data->pwm = pwm;

	data->out_port.num_modes = NUM_EV3_OUTPUT_PORT_MODE;
	data->out_port.mode_info = legoev3_output_port_mode_info;
	data->out_port.set_mode = ev3_output_port_set_mode;
	data->out_port.set_device = ev3_output_port_set_device;
	data->out_port.get_status = ev3_output_port_get_status;
	data->out_port.dc_motor_ops = &ev3_output_port_motor_ops;
	data->out_port.context = data;
	err = lego_port_register(&data->out_port, &ev3_output_port_type, parent);
	if (err) {
		dev_err(parent, "Failed to register lego_port_device. (%d)\n",
			err);
		goto err_lego_port_register;
	}

	INIT_WORK(&data->change_uevent_work, ev3_output_port_change_uevent_work);
	INIT_WORK(&data->work, NULL);

	data->con_state = CON_STATE_INIT;

	hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	data->timer.function = ev3_output_port_timer_callback;
	hrtimer_start(&data->timer, ktime_set(0, OUTPUT_PORT_POLL_NS),
		      HRTIMER_MODE_REL);

	return &data->out_port;

err_lego_port_register:
	pwm_disable(pwm);
err_pwm_start:
err_pwm_config:
	pwm_put(pwm);
err_pwm_get:
	gpio_free_array(data->gpio, ARRAY_SIZE(data->gpio));
err_gpio_request_array:
	put_legoev3_analog(data->analog);
err_request_legoev3_analog:
	kfree(data);

	return ERR_PTR(err);
}
Example #4
0
UBYTE pwm_send(UBYTE *resp, UBYTE len, UBYTE *msg, UBYTE msg_len)
{
	UBYTE ret,i,j;
	UBYTE message[20];
	UBYTE done;

	if (msg_len>6)
	{
		printf("Error: PWM message allows only 7 bytes\n\r");
		return 0;
	}
 	//OK we need to build the message
	message[0]=0x61;
	message[1]=0x6A;
	message[2]=0xF1;

	for(i=0; i<msg_len; i++)
	{
		message[3+i]=msg[i];
	}

	i=3+i;
	message[i]=crc(message,i);
	i++;
/*
	printf("Sending: ");
	for(ret=0; ret<i; ret++)
	{
		printf("%X ",message[ret]);
	}
*/
	//now we can send message
	for(j=0; j<3; j++)
	{
		ret=pwm_put(message,i,2000);
		if (ret==i)
			break;
	}
	if(ret!=i)
	{
		printf("Error: PWM message sending problems %d\n\r",ret);
		return 0;
	}
	//now lets get response
	//delay_us(500);
	//printf("calling PWM get\n\r");
	//ret=pwm_get(resp,len,2000);

	done=0;
	i=0;
	while(!done)
	{
		ret=pwm_rx(resp,len,2000);
		if (ret>5)
		{
			if (resp[0]==0x41)
				done=1;
		}
		i++;
		if (i>20)
			done=1;
	}

			
				//ret=pwm_rx(resp,len,2000);
	//ret=pwm_rx(resp,len,2000);
/*
	printf("\tRx: ");
	for(i=0; i<ret; i++)
	{
		printf("%X ",resp[i]);
	}
	printf("\n\r");
*/

	return ret;
}
Example #5
0
static void pwm_release(void)
{
	pwm_put(pwm_dev);
}