Beispiel #1
0
void InitGPIO2(void) {
  (*GPSR) = (1 << 4) | (1<< 7);
  (*baseloop) = MS_TO_NS(100);
  (*leftloop) = MS_TO_NS(1);
  (*rightloop) = MS_TO_NS(1);

  fp = fopen("/dev/lart", "wb");

  if((int)fp < 0) {
    printf("Can't open /dev/lart\n");
  }

}
int Mutex_Lock(IN HANDLE hm, IN DWORD dwWaitTimeout)
{
	MUTEX	*pMutex = (MUTEX *)hm;
	struct	timespec ts;
	long	nWaitSeconds, nWaitNonaseconds;
	time_t	tmEndTime;
	
	if (hm == NULL)
	{
		return ERR_INVALID_ARGS;
	}

	nWaitSeconds		= (long)MS_TO_SEC(dwWaitTimeout);			// sec
	nWaitNonaseconds	= (long)MS_TO_NS(dwWaitTimeout%MS_PER_SEC);	// nonasec

	clock_gettime(CLOCK_REALTIME, &ts);	// get the start time.
	
	ts.tv_nsec += nWaitNonaseconds;
	if (ts.tv_nsec > NS_PER_SEC)
	{
		ts.tv_sec  += 1;
		ts.tv_nsec -= NS_PER_SEC;
	}

	tmEndTime = ts.tv_sec;

#ifdef _DEBUG_MUTEX
	TRACE("[Mutex_Lock] -- lock and wait %d ms at %d\n", 
		(int)dwWaitTimeout, (int)tmEndTime);
#endif //_DEBUG_MUTEX

	while (nWaitSeconds >= 0)
	{
		// get the end of the real time.
		tmEndTime += ((nWaitSeconds < MAX_WAIT_INTERVAL) ? nWaitSeconds
			: MAX_WAIT_INTERVAL);

		ts.tv_sec = tmEndTime;
		// do NOT change ts.tv_nsec.

		if (pthread_mutex_timedlock(&pMutex->hInternalMutex, &ts) == 0)
		{
			return ERR_MUTEX_OK;
		}

		nWaitSeconds -= MAX_WAIT_INTERVAL;
		if (nWaitSeconds >= 0)
		{
			RUN_THREAD_HEARTBEAT();
		}
	}

#ifdef _DEBUG_MUTEX
	TRACE("[Mutex_Lock] -- lock timeouted at %d\n", 
		(int)time(NULL));
#endif //_DEBUG_MUTEX

	// if goes here, timeout on trying to lock.
	return ERR_MUTEX_TIMEOUT;
}
Beispiel #3
0
static void taskManager(
    void *              arg) {

    int                 retval;

    (void)arg;

    retval = appInit();

    if (0 != retval) {
        LOG_ERR("could not start the application, err: %s. Exiting", strerror(retval));
        appTerm();
        kill(
            getpid(),
            SIGTERM);

        return;
    }
    rt_task_sleep(
        MS_TO_NS(2000));
    appTerm();
    printf("a: %u, b: %u\n", A, B);
    buff[sizeof(buff) - 1] = 0;
    printf("buff: \n%s\n", buff);
    kill(getpid(), SIGTERM);
}
Beispiel #4
0
static u32 redrat3_get_timeout(struct device *dev,
			       struct rc_dev *rc, struct usb_device *udev)
{
	u32 *tmp;
	u32 timeout = MS_TO_NS(150); /* a sane default, if things go haywire */
	int len, ret, pipe;

	len = sizeof(*tmp);
	tmp = kzalloc(len, GFP_KERNEL);
	if (!tmp) {
		dev_warn(dev, "Memory allocation faillure\n");
		return timeout;
	}

	pipe = usb_rcvctrlpipe(udev, 0);
	ret = usb_control_msg(udev, pipe, RR3_GET_IR_PARAM,
			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
			      RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5);
	if (ret != len) {
		dev_warn(dev, "Failed to read timeout from hardware\n");
		return timeout;
	}

	timeout = US_TO_NS(redrat3_len_to_us(be32_to_cpu(*tmp)));
	if (timeout < rc->min_timeout)
		timeout = rc->min_timeout;
	else if (timeout > rc->max_timeout)
		timeout = rc->max_timeout;

	rr3_dbg(dev, "Got timeout of %d ms\n", timeout / (1000 * 1000));
	return timeout;
}
/*
 * init
 */
int hps_core_init(void)
{
	int r = 0;

	hps_warn("hps_core_init\n");
	if (hps_ctxt.periodical_by == HPS_PERIODICAL_BY_TIMER) {
		/*init timer */
		init_timer(&hps_ctxt.tmr_list);
		/*init_timer_deferrable(&hps_ctxt.tmr_list); */
		hps_ctxt.tmr_list.function = (void *)&_hps_timer_callback;
		hps_ctxt.tmr_list.data = (unsigned long)&hps_ctxt;
		hps_ctxt.tmr_list.expires = jiffies + msecs_to_jiffies(HPS_TIMER_INTERVAL_MS);
		add_timer(&hps_ctxt.tmr_list);
	} else if (hps_ctxt.periodical_by == HPS_PERIODICAL_BY_HR_TIMER) {
		ktime = ktime_set(0, MS_TO_NS(HPS_TIMER_INTERVAL_MS));
		/*init Hrtimer */
		hrtimer_init(&hps_ctxt.hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		hps_ctxt.hr_timer.function = (void *)&_hps_timer_callback;
		hrtimer_start(&hps_ctxt.hr_timer, ktime, HRTIMER_MODE_REL);

	}
	/* init and start task */
	r = hps_task_start();
	if (r)
		hps_error("hps_task_start fail(%d)\n", r);

	return r;
}
void create_process(int depth, char** argv)
{
	int pid, status;

	// Jeśli dziecko
	if((pid = fork()) == 0)
	{
		if(depth > 0)
			create_process(depth - 1, argv);	
		printf("Rozpoczęcie procesu potomnego %d, pid %d\n", depth, getpid());
		struct timespec t = {0, MS_TO_NS(500)};
		int i;
		int steps = atoi(argv[depth + 2]);
		for(i = 0; i <= steps; ++i)
		{
			printf("Potomny %d, krok %d/%d\n", depth, i, steps);
			nanosleep(&t, NULL);
		}
		printf("Koniec procesu potomnego %d, pid %d\n", depth, getpid());

		if(depth > 0)
		{
			pid = wait(&status);
			printf("Proces %d, zakończony: kod %d\n", pid, WEXITSTATUS(status));
		}
		
		exit(depth);
	}
}
Beispiel #7
0
static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
{
	struct device *dev = rr3->dev;
	struct rc_dev *rc;
	int ret = -ENODEV;
	u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct);

	rc = rc_allocate_device();
	if (!rc) {
		dev_err(dev, "remote input dev allocation failed\n");
		goto out;
	}

	snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s "
		 "Infrared Remote Transceiver (%04x:%04x)",
		 prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "",
		 le16_to_cpu(rr3->udev->descriptor.idVendor), prod);

	usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys));

	rc->input_name = rr3->name;
	rc->input_phys = rr3->phys;
	usb_to_input_id(rr3->udev, &rc->input_id);
	rc->dev.parent = dev;
	rc->priv = rr3;
	rc->driver_type = RC_DRIVER_IR_RAW;
	rc->allowed_protos = RC_TYPE_ALL;
	rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT);
	rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT);
	rc->timeout = redrat3_get_timeout(dev, rc, rr3->udev);
	rc->tx_ir = redrat3_transmit_ir;
	rc->s_tx_carrier = redrat3_set_tx_carrier;
	rc->driver_name = DRIVER_NAME;
	rc->map_name = RC_MAP_HAUPPAUGE;

	ret = rc_register_device(rc);
	if (ret < 0) {
		dev_err(dev, "remote dev registration failed\n");
		goto out;
	}

	return rc;

out:
	rc_free_device(rc);
	return NULL;
}
Beispiel #8
0
static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
{
	struct device *dev = rr3->dev;
	struct rc_dev *rc;
	int ret;
	u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct);

	rc = rc_allocate_device(RC_DRIVER_IR_RAW);
	if (!rc)
		return NULL;

	snprintf(rr3->name, sizeof(rr3->name),
		 "RedRat3%s Infrared Remote Transceiver",
		 prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "");

	usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys));

	rc->device_name = rr3->name;
	rc->input_phys = rr3->phys;
	usb_to_input_id(rr3->udev, &rc->input_id);
	rc->dev.parent = dev;
	rc->priv = rr3;
	rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
	rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT);
	rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT);
	rc->timeout = US_TO_NS(redrat3_get_timeout(rr3));
	rc->s_timeout = redrat3_set_timeout;
	rc->tx_ir = redrat3_transmit_ir;
	rc->s_tx_carrier = redrat3_set_tx_carrier;
	rc->s_carrier_report = redrat3_wideband_receiver;
	rc->driver_name = DRIVER_NAME;
	rc->rx_resolution = US_TO_NS(2);
	rc->map_name = RC_MAP_HAUPPAUGE;

	ret = rc_register_device(rc);
	if (ret < 0) {
		dev_err(dev, "remote dev registration failed\n");
		goto out;
	}

	return rc;

out:
	rc_free_device(rc);
	return NULL;
}
Beispiel #9
0
static int __init hrt_init(void)
{
	
	printk( "HELLO HR TIMER Test\n" );
	
	hrt_hrtimer_init( 0L, MS_TO_NS(1L) );
	
	printk( "Starting hrtimer\n");
	hrt_hrtimer_start();

	return 0;
}
Beispiel #10
0
static int __init mod_init(void)
{
	ktime_t ktime;
	unsigned long delay_in_ms = 200L;
	pr_info("HR Timer module installing\n");
	ktime = ktime_set(0, MS_TO_NS(delay_in_ms));
	hrtimer_init(&hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hr_timer.function = &my_hrtimer_callback;
	pr_info("Starting timer to fire in %ldms (%ld)\n",
			delay_in_ms, jiffies);
	hrtimer_start(&hr_timer, ktime, HRTIMER_MODE_REL);
	return 0;
}
int main(void) 
{
	struct timespec t = {0, MS_TO_NS(50)};
	int i,j;
	puts("Witamy w Lab PRW");
	system("hostname");
		for(i=0;i<10;i++) 
		{
			j=i+10;
			printf("Krok %d\n",i);
			nanosleep(&t, NULL);
		}
	printf("Koniec\n");
	return EXIT_SUCCESS;
}
Beispiel #12
0
/**
 * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
 * @dev:	the struct rc_dev device descriptor
 * @type:	the type of the event that has occurred
 *
 * This routine (which may be called from an interrupt context) is used to
 * store the beginning of an ir pulse or space (or the start/end of ir
 * reception) for the raw ir decoding state machines. This is used by
 * hardware which does not provide durations directly but only interrupts
 * (or similar events) on state change.
 */
int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type)
{
	ktime_t			now;
	s64			delta; /* ns */
	DEFINE_IR_RAW_EVENT(ev);
	int			rc = 0;
	int			delay;

	if (!dev->raw)
		return -EINVAL;

	now = ktime_get();
	delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
	delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]);

	/* Check for a long duration since last event or if we're
	 * being called for the first time, note that delta can't
	 * possibly be negative.
	 */
	if (delta > delay || !dev->raw->last_type)
		type |= IR_START_EVENT;
	else
		ev.duration = delta;

	if (type & IR_START_EVENT)
		ir_raw_event_reset(dev);
	else if (dev->raw->last_type & IR_SPACE) {
		ev.pulse = false;
		rc = ir_raw_event_store(dev, &ev);
	} else if (dev->raw->last_type & IR_PULSE) {
		ev.pulse = true;
		rc = ir_raw_event_store(dev, &ev);
	} else
		return 0;

	dev->raw->last_event = now;
	dev->raw->last_type = type;
	return rc;
}
int main(int argc, char** argv)
{
	int pid, child, parent;
	parent = getpid();
	printf("Rozpoczęcie procesu macierzystego, pid %d\n", getpid());
	create_process(argc - 3, argv);
	// for(child = 2; child < argc; ++child)
	// {
		
	// }

	// Jeśli rodzic
	if(getpid() == parent)
	{
		printf("Rozpoczęcie pętli procesu macierzystego, pid %d\n", getpid());
		struct timespec t = {0, MS_TO_NS(500)};
		int i;
		int steps = atoi(argv[1]);
		for(i = 0; i <= steps; ++i)
		{
			printf("Macierzysty, krok %d/%d\n", i, steps);
			nanosleep(&t, NULL);
		}
		printf("Zakończenie pętli procesu macierzystego, pid %d\n", getpid());
	}
	
	int status;
	pid = wait(&status);
	printf("Proces %d, zakończony: kod %d\n", pid, WEXITSTATUS(status));
	
	// int i, status;
	// for(i = 0; i < argc - 2; ++i)
	// {
	// 	pid = wait(&status);
	// 	printf("Proces %d, zakończony: kod %d\n", pid, WEXITSTATUS(status));
	// }
	// printf("Zakończenie procesu macierzystego, pid %d\n", getpid());
	return 0;
}
Beispiel #14
0
static void taskB(
    void *              arg) {

    (void)arg;

    taskPrintInfo();
    B = 0ULL;

    while (1) {
        LOG_DBG("B signal");
        rt_sem_v(
            &Sem);
        LOG_DBG("B signaled");
        B++;
        printf("B: %d\n", B);
        rt_task_sleep(MS_TO_NS(10));

        if (B == 10) {

            return;
        }
    }
}
/* 10Hz Timer Callback */
enum hrtimer_restart timer10HzCallback( struct hrtimer* sample ) {

	ktime_t k10Hz;

	if((dispatchFlag & (1 << TEN_HZ_FLAG)) && !(dispatchFlag & (1 << OVERRUN_FLAG))) {

		dispatchFlag &= ~(1 << TEN_HZ_FLAG);

		up( &tenHzSemph );
		/* Check if my 1Hz Task is complete. If it is complete, handover the semaphore */
		//printk( "10 Hz Timer Callback initiated\n");
		k10Hz = ktime_set( 0, MS_TO_NS(97) ); 	//100ms -> 10hz
		hrtimer_forward_now(sample, k10Hz);
		return HRTIMER_RESTART;
	}
	
	else {
			dispatchFlag |= (1 << OVERRUN_FLAG);	
			up ( &exitSemph );
			return HRTIMER_NORESTART;
	}

}
/* initialize CIR input device */
int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
{
	struct rc_dev *rdev;
	int ret = 0;

	rdev = rc_allocate_device();
	if (!rdev)
		return -ENOMEM;

	rdev->priv             = data;
	rdev->driver_type      = RC_DRIVER_IR_RAW;
	rdev->allowed_protos   = RC_BIT_ALL;
	rdev->open             = picolcd_cir_open;
	rdev->close            = picolcd_cir_close;
	rdev->input_name       = data->hdev->name;
	rdev->input_phys       = data->hdev->phys;
	rdev->input_id.bustype = data->hdev->bus;
	rdev->input_id.vendor  = data->hdev->vendor;
	rdev->input_id.product = data->hdev->product;
	rdev->input_id.version = data->hdev->version;
	rdev->dev.parent       = &data->hdev->dev;
	rdev->driver_name      = PICOLCD_NAME;
	rdev->map_name         = RC_MAP_RC6_MCE;
	rdev->timeout          = MS_TO_NS(100);
	rdev->rx_resolution    = US_TO_NS(1);

	ret = rc_register_device(rdev);
	if (ret)
		goto err;
	data->rc_dev = rdev;
	return 0;

err:
	rc_free_device(rdev);
	return ret;
}
Beispiel #17
0
void game_update_and_render(RenderQueue* render_queue, Game* game, Input* input,
                            u64 dt) {
    if (game->entities.entity_count == 0) {
        V2i pos;
        pos.x = 7;
        pos.y = 5;
        u32 id = spawn_entity(&game->entities);
        register_location(&game->entities, id, pos, SOUTH);
        register_appearance(&game->entities, id, 7723);
        register_controlled(&game->entities, id);
    }

    // Handle user input

    if (input->keys[ESCAPE] != 0) {
        game->should_end = true;
    }
    u32 entity_to_control_mask_include =
        ENTITY_LOCATED_BIT | ENTITY_CONTROLLED_BIT;
    u32 entity_to_control_mask_exclude = ENTITY_MOVING_BIT;
    u32 entity_to_control_count = 0;
    u32 entity_to_control[MAX_ENTITY_COUNT];
    filter_entities(&game->entities, entity_to_control_mask_include,
                    entity_to_control_mask_exclude, entity_to_control,
                    &entity_to_control_count);
    V2i positions[MAX_ENTITY_COUNT];
    for (u32 i = 0; i < entity_to_control_count; i++) {
        for (u32 j = 0; j < game->entities.located_count; j++) {
            if (entity_to_control[i] == game->entities.located[j]) {
                positions[i] = game->entities.positions[j];
                break;
            }
        }
    }
    bool moved = false;
    Direction direction = NORTH;
    V2i destination_diff;
    for (u32 i = 1; i < 5; i++) {
        i32 key_state = input->keys[i] + game->previous_key_state[i];
        if (key_state && entity_to_control_count > 0) {
            moved = true;
            destination_diff.x = 0;
            destination_diff.y = 0;
            switch (i) {
            case W:
                direction = NORTH;
                destination_diff.y -= 1;
                break;
            case A:
                direction = WEST;
                destination_diff.x -= 1;
                break;
            case S:
                direction = SOUTH;
                destination_diff.y += 1;
                break;
            case D:
                direction = EAST;
                destination_diff.x += 1;
                break;
            default:
                assert(!(bool)"Unreachable!");
                break;
            }
        }
        game->previous_key_state[i] = key_state % 2;
    }
    if (moved) {
        for (u32 j = 0; j < entity_to_control_count; j++) {
            f32 distance = 0.0f;
            V2i destination;
            destination.x = positions[j].x + destination_diff.x;
            destination.y = positions[j].y + destination_diff.y;
            u32 id = entity_to_control[j];
            register_moving(&game->entities, id, destination, distance);
            update_located_direction(&game->entities, id, direction);
        }
    }

    // Update

    game->tick += dt;
    if (game->tick > MS_TO_NS(2000)) {
        game->tick = 0;
        for (int y = 0; y < 11; y++) {
            for (int x = 0; x < 15; x++) {
                game->tiles[x][y] = rand() % 101925;
            }
        }
    }

    { // Update moving entities
        u32 movable_mask = ENTITY_LOCATED_BIT | ENTITY_MOVING_BIT;
        u32 entities_to_move_count = 0;
        u32 entities_to_move[MAX_ENTITY_COUNT];
        filter_entities(&game->entities, movable_mask, 0, entities_to_move,
                        &entities_to_move_count);

        u32 not_moving_count = 0;
        u32 not_moving[MAX_ENTITY_COUNT];
        for (u32 i = 0; i < entities_to_move_count; i++) {
            u32 id = entities_to_move[i];

            u32 located_index = 0;
            for (u32 j = 0; j < game->entities.located_count; j++) {
                if (game->entities.located[j] == id) {
                    located_index = j;
                    break;
                }
            }

            u32 moving_index = 0;
            for (u32 j = 0; j < game->entities.moving_count; j++) {
                if (game->entities.moving[j] == id) {
                    moving_index = j;
                    break;
                }
            }

            if (game->entities.distances[moving_index] >= 1.0f) {
                game->entities.positions[located_index] =
                    game->entities.destinations[moving_index];
                game->entities.distances[moving_index] = 0.0f;
                not_moving[not_moving_count] = id;
                not_moving_count += 1;
            } else {
                game->entities.distances[moving_index] += 0.1f;
            }
        }

        for (u32 i = 0; i < not_moving_count; i++) {
            deregister_moving(&game->entities, not_moving[i]);
        }
    }

    // Render

    render_queue_push_clear(render_queue, 0.0f, 0.0f, 0.0f, 0.0f);

    game->camera_x = 7.0f;
    game->camera_y = 5.0f;

    u32 tile_size = 64;
    for (u32 r = 0; r < 128; r++) {
        for (u32 c = 0; c < 128; c++) {
            f32 x = c - game->camera_x + 7;
            f32 y = r - game->camera_y + 5;
            if (0.0f <= x && x < 16.0f && 0 <= y && y < 12.0f) {
                render_queue_push_sprite(render_queue, game->world[r][c],
                                         (i32)(x * tile_size + tile_size),
                                         (i32)(y * tile_size + tile_size),
                                         tile_size);
            }
        }
    }

    u32 drawable_mask = ENTITY_LOCATED_BIT | ENTITY_APPEARANCE_BIT;
    u32 entities_to_draw_count = 0;
    u32 entities_to_draw[MAX_ENTITY_COUNT];
    filter_entities(&game->entities, drawable_mask, 0, entities_to_draw,
                    &entities_to_draw_count);

    u32 ms[MAX_ENTITY_COUNT];
    for (u32 i = 0; i < entities_to_draw_count; i++) {
        for (u32 j = 0; j < game->entities.entity_count; j++) {
            if (entities_to_draw[i] == game->entities.ids[j]) {
                assert((game->entities.masks[j] & drawable_mask) ==
                       drawable_mask);
                ms[i] = game->entities.masks[j];
                break;
            }
        }
    }
    u32 ss[MAX_ENTITY_COUNT];
    for (u32 i = 0; i < entities_to_draw_count; i++) {
        u32 id = entities_to_draw[i];
        for (u32 j = 0; j < game->entities.appearance_count; j++) {
            if (game->entities.appearance[j] == id) {
                ss[i] = game->entities.sprites[j];
                break;
            }
        }
    }
    f32 xs[MAX_ENTITY_COUNT];
    f32 ys[MAX_ENTITY_COUNT];
    Direction dirs[MAX_ENTITY_COUNT];
    for (u32 i = 0; i < entities_to_draw_count; i++) {
        u32 id = entities_to_draw[i];
        for (u32 j = 0; j < game->entities.located_count; j++) {
            if (game->entities.located[j] == id) {
                xs[i] = (f32)game->entities.positions[j].x;
                ys[i] = (f32)game->entities.positions[j].y;
                dirs[i] = game->entities.directions[j];
                break;
            }
        }
    }
    f32 dists[MAX_ENTITY_COUNT];
    for (u32 i = 0; i < entities_to_draw_count; i++) {
        for (u32 j = 0; j < game->entities.moving_count; j++) {
            if (entities_to_draw[i] == game->entities.moving[j]) {
                dists[i] = game->entities.distances[j];
                break;
            }
        }
    }

    for (u32 i = 0; i < entities_to_draw_count; i++) {
        u32 sprite_offset = 0;
        if (ms[i] & ENTITY_MOVING_BIT) {
            f32 animation_frames = 4.0f;
            f32 n = (dists[i] / (1.0f / animation_frames));
            sprite_offset += (u32)n * 4;
            switch (dirs[i]) {
            case NORTH:
            case SOUTH:
                sprite_offset += ((u32)ys[i] % 2) * (4 * 4);
                break;
            case WEST:
            case EAST:
                sprite_offset += ((u32)xs[i] % 2) * (4 * 4);
                break;
            }
        }
        switch (dirs[i]) {
        case NORTH:
            ss[i] = 7721 + sprite_offset;
            break;
        case EAST:
            ss[i] = 7722 + sprite_offset;
            break;
        case SOUTH:
            ss[i] = 7723 + sprite_offset;
            break;
        case WEST:
            ss[i] = 7724 + sprite_offset;
            break;
        }
    }
    for (u32 i = 0; i < entities_to_draw_count; i++) {
        if (ms[i] & ENTITY_MOVING_BIT) {
            V2f v;
            v.x = xs[i];
            v.y = ys[i];
            for (u32 j = 0; j < game->entities.moving_count; j++) {
                if (game->entities.moving[j] == entities_to_draw[i]) {
                    switch (game->entities.directions[j]) {
                    case NORTH:
                        v.y -= game->entities.distances[j];
                        break;
                    case WEST:
                        v.x -= game->entities.distances[j];
                        break;
                    case SOUTH:
                        v.y += game->entities.distances[j];
                        break;
                    case EAST:
                        v.x += game->entities.distances[j];
                        break;
                    }
                    break;
                }
            }
            xs[i] = v.x - game->camera_x + 7.0f;
            ys[i] = v.y - game->camera_y + 5.0f;
        }
    }

    for (u32 i = 0; i < entities_to_draw_count; i++) {
        i32 ts = (i32)tile_size;
        render_queue_push_sprite(render_queue, ss[i], (i32)(xs[i] * ts + ts),
                                 (i32)(ys[i] * ts + ts), ts);
    }
}
Beispiel #18
0
static int sunxi_ir_probe(struct platform_device *pdev)
{
    int ret = 0;
    unsigned long tmp = 0;

    struct device *dev = &pdev->dev;
    struct device_node *dn = dev->of_node;
    struct resource *res;
    struct sunxi_ir *ir;

    ir = devm_kzalloc(dev, sizeof(struct sunxi_ir), GFP_KERNEL);
    if (!ir)
        return -ENOMEM;

    if (of_device_is_compatible(dn, "allwinner,sun5i-a13-ir"))
        ir->fifo_size = 64;
    else
        ir->fifo_size = 16;

    /* Clock */
    ir->apb_clk = devm_clk_get(dev, "apb");
    if (IS_ERR(ir->apb_clk)) {
        dev_err(dev, "failed to get a apb clock.\n");
        return PTR_ERR(ir->apb_clk);
    }
    ir->clk = devm_clk_get(dev, "ir");
    if (IS_ERR(ir->clk)) {
        dev_err(dev, "failed to get a ir clock.\n");
        return PTR_ERR(ir->clk);
    }

    /* Reset (optional) */
    ir->rst = devm_reset_control_get_optional(dev, NULL);
    if (IS_ERR(ir->rst)) {
        ret = PTR_ERR(ir->rst);
        if (ret == -EPROBE_DEFER)
            return ret;
        ir->rst = NULL;
    } else {
        ret = reset_control_deassert(ir->rst);
        if (ret)
            return ret;
    }

    ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK);
    if (ret) {
        dev_err(dev, "set ir base clock failed!\n");
        goto exit_reset_assert;
    }

    if (clk_prepare_enable(ir->apb_clk)) {
        dev_err(dev, "try to enable apb_ir_clk failed\n");
        ret = -EINVAL;
        goto exit_reset_assert;
    }

    if (clk_prepare_enable(ir->clk)) {
        dev_err(dev, "try to enable ir_clk failed\n");
        ret = -EINVAL;
        goto exit_clkdisable_apb_clk;
    }

    /* IO */
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    ir->base = devm_ioremap_resource(dev, res);
    if (IS_ERR(ir->base)) {
        dev_err(dev, "failed to map registers\n");
        ret = PTR_ERR(ir->base);
        goto exit_clkdisable_clk;
    }

    ir->rc = rc_allocate_device();
    if (!ir->rc) {
        dev_err(dev, "failed to allocate device\n");
        ret = -ENOMEM;
        goto exit_clkdisable_clk;
    }

    ir->rc->priv = ir;
    ir->rc->input_name = SUNXI_IR_DEV;
    ir->rc->input_phys = "sunxi-ir/input0";
    ir->rc->input_id.bustype = BUS_HOST;
    ir->rc->input_id.vendor = 0x0001;
    ir->rc->input_id.product = 0x0001;
    ir->rc->input_id.version = 0x0100;
    ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL);
    ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
    ir->rc->dev.parent = dev;
    ir->rc->driver_type = RC_DRIVER_IR_RAW;
    ir->rc->allowed_protocols = RC_BIT_ALL;
    ir->rc->rx_resolution = SUNXI_IR_SAMPLE;
    ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT);
    ir->rc->driver_name = SUNXI_IR_DEV;

    ret = rc_register_device(ir->rc);
    if (ret) {
        dev_err(dev, "failed to register rc device\n");
        goto exit_free_dev;
    }

    platform_set_drvdata(pdev, ir);

    /* IRQ */
    ir->irq = platform_get_irq(pdev, 0);
    if (ir->irq < 0) {
        dev_err(dev, "no irq resource\n");
        ret = ir->irq;
        goto exit_free_dev;
    }

    ret = devm_request_irq(dev, ir->irq, sunxi_ir_irq, 0, SUNXI_IR_DEV, ir);
    if (ret) {
        dev_err(dev, "failed request irq\n");
        goto exit_free_dev;
    }

    /* Enable CIR Mode */
    writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG);

    /* Set noise threshold and idle threshold */
    writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE)|REG_CIR_ITHR(SUNXI_IR_RXIDLE),
           ir->base + SUNXI_IR_CIR_REG);

    /* Invert Input Signal */
    writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);

    /* Clear All Rx Interrupt Status */
    writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);

    /*
     * Enable IRQ on overflow, packet end, FIFO available with trigger
     * level
     */
    writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN |
           REG_RXINT_RAI_EN | REG_RXINT_RAL(ir->fifo_size / 2 - 1),
           ir->base + SUNXI_IR_RXINT_REG);

    /* Enable IR Module */
    tmp = readl(ir->base + SUNXI_IR_CTL_REG);
    writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG);

    dev_info(dev, "initialized sunXi IR driver\n");
    return 0;

exit_free_dev:
    rc_free_device(ir->rc);
exit_clkdisable_clk:
    clk_disable_unprepare(ir->clk);
exit_clkdisable_apb_clk:
    clk_disable_unprepare(ir->apb_clk);
exit_reset_assert:
    if (ir->rst)
        reset_control_assert(ir->rst);

    return ret;
}
/* Function Declaration for threads */
int oneHzDispatch(void* data) {

	int retval = 0;

	struct sched_param param = { .sched_priority = 95 };
	sched_setscheduler(current, SCHED_FIFO, &param);

	/* Wait for semaphore. Get it*/
	while(1) {
		if( ( retval = down_killable( &oneHzSemph ) ))
			return retval;
		
		oneHzFunc( NULL );

		if( !(dispatchFlag & (1 << OVERRUN_FLAG)))
			dispatchFlag |= (1 << ONE_HZ_FLAG);
	}

}

int tenHzDispatch(void* data) {

	int retval = 0;

	struct sched_param param = { .sched_priority = 96 };
	sched_setscheduler(current, SCHED_FIFO, &param);

	/* Wait for semaphore. Get it*/
	/* Call User function here */
	while(1) {
		if( ( retval = down_killable( &tenHzSemph ) ))
			return retval;

		tenHzFunc( NULL );

		if( !(dispatchFlag & (1 << OVERRUN_FLAG)))
			dispatchFlag |= (1 << TEN_HZ_FLAG);
	}
	
}

int hunHzDispatch(void* data) {

	/* Wait for semaphore. Get it*/
	/* Call User function here */
	int retval = 0;

	struct sched_param param = { .sched_priority = 97 };
	sched_setscheduler(current, SCHED_FIFO, &param);

	while(1) {
	if( ( retval = down_killable( &hunHzSemph ) ))
		return retval;

	hunHzFunc( NULL );

	if( !(dispatchFlag & (1 << OVERRUN_FLAG)))
		dispatchFlag |= (1 << HUN_HZ_FLAG);
	}

}

int exitSched(void *data){

	struct sched_param param = { .sched_priority = 98 };
	sched_setscheduler(current, SCHED_FIFO, &param);

	down_killable( &exitSemph );
	

	printk( KERN_ERR "Task overrun!!\n");

	if( !(dispatchFlag & (1 << ONE_HZ_FLAG)))
		printk(KERN_ERR "Possibly 1Hz Task\n");

	if( !(dispatchFlag & (1 << TEN_HZ_FLAG)))
		printk(KERN_ERR "Possibly 10Hz Task\n");


	if( !(dispatchFlag & (1 << HUN_HZ_FLAG)))
		printk(KERN_ERR "Possibly 100Hz Task\n");

	kthread_stop( task1Hz );
	kthread_stop( task10Hz ); 
	kthread_stop( task100Hz ); 

	

	return 0;

}

static int __init p_scheduler_init( void ) {


	/* Create Semaphores here */
	int retval = 0;
	ktime_t k1Hz, k10Hz, k100Hz;

	sema_init( &oneHzSemph, 1 );
	sema_init( &tenHzSemph, 1 );
	sema_init( &hunHzSemph, 1 );
	sema_init( &exitSemph, 1 );

	dispatchFlag = 0xFF;
	dispatchFlag &= ~( 1 << OVERRUN_FLAG );
	


	if( (retval = down_killable( &oneHzSemph)) ) {
		printk(KERN_ERR "Cannot acquire one hertz semaphore\n");
	 	return retval;
	 }

	if( (retval = down_killable( &tenHzSemph)) ) {
		printk(KERN_ERR "Cannot acquire ten hertz semaphore\n");
	 	return retval;
	 }

 	if( (retval = down_killable( &hunHzSemph)) ) {
 		printk(KERN_ERR "Cannot acquire hundred hertz semaphore\n");
	 	return retval;
	 }

	 if( (retval = down_killable( &exitSemph)) ) {
	 	printk(KERN_ERR "Cannot acquire exit semaphore\n");
	 	return retval;
	 }



	/* Start and initialize your timers */

	/* Thread Creation */
	exitThread = kthread_run( exitSched, NULL, "CleanupThread");
	task100Hz = kthread_run( hunHzDispatch, NULL, "Thread100Hz");
	task10Hz = kthread_run( tenHzDispatch, NULL, "Thread10Hz");
	task1Hz = kthread_run( oneHzDispatch, NULL, "Thread1Hz");

	k1Hz   	= ktime_set( 0, MS_TO_NS(997) ); 	//1000ms -> 1hz
	k10Hz  	= ktime_set( 0, MS_TO_NS(97) ); 	//100ms -> 10hz
	k100Hz 	= ktime_set( 0, MS_TO_NS(23) ); 	//10ms -> 100hz

	hrtimer_init( &timer100Hz, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
	hrtimer_init( &timer10Hz, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
	hrtimer_init( &timer1Hz, CLOCK_MONOTONIC, HRTIMER_MODE_REL );

	timer1Hz.function 	= 	&timer1HzCallback;
	timer10Hz.function 	=	&timer10HzCallback;	
	timer100Hz.function =	&timer100HzCallback;

	printk("Starting Timers\n");

	hrtimer_start( &timer100Hz, k100Hz, HRTIMER_MODE_REL);
	hrtimer_start( &timer10Hz, k10Hz, HRTIMER_MODE_REL);
	hrtimer_start( &timer1Hz, k1Hz, HRTIMER_MODE_REL);

	return 0;

}

static void __exit p_scheduler_cleanup( void ) {

	int retAllTimers;

	retAllTimers = hrtimer_cancel( &timer1Hz ) && hrtimer_cancel( &timer10Hz ) && hrtimer_cancel( &timer100Hz );

	if( retAllTimers )
		printk("Timers still in use\n");

	printk("Cancelling All Timers\n");
	up( &exitSemph );

	return;

}
Beispiel #20
0
struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
					 void *priv, const char *name, u32 caps,
					 u8 available_las)
{
	struct cec_adapter *adap;
	int res;

	if (WARN_ON(!caps))
		return ERR_PTR(-EINVAL);
	if (WARN_ON(!ops))
		return ERR_PTR(-EINVAL);
	if (WARN_ON(!available_las || available_las > CEC_MAX_LOG_ADDRS))
		return ERR_PTR(-EINVAL);
	adap = kzalloc(sizeof(*adap), GFP_KERNEL);
	if (!adap)
		return ERR_PTR(-ENOMEM);
	strlcpy(adap->name, name, sizeof(adap->name));
	adap->phys_addr = CEC_PHYS_ADDR_INVALID;
	adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
	adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
	adap->capabilities = caps;
	adap->available_log_addrs = available_las;
	adap->sequence = 0;
	adap->ops = ops;
	adap->priv = priv;
	memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs));
	mutex_init(&adap->lock);
	INIT_LIST_HEAD(&adap->transmit_queue);
	INIT_LIST_HEAD(&adap->wait_queue);
	init_waitqueue_head(&adap->kthread_waitq);

	adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);
	if (IS_ERR(adap->kthread)) {
		pr_err("cec-%s: kernel_thread() failed\n", name);
		res = PTR_ERR(adap->kthread);
		kfree(adap);
		return ERR_PTR(res);
	}

	if (!(caps & CEC_CAP_RC))
		return adap;

#if IS_REACHABLE(CONFIG_RC_CORE)
	/* Prepare the RC input device */
	adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE);
	if (!adap->rc) {
		pr_err("cec-%s: failed to allocate memory for rc_dev\n",
		       name);
		kthread_stop(adap->kthread);
		kfree(adap);
		return ERR_PTR(-ENOMEM);
	}

	snprintf(adap->input_name, sizeof(adap->input_name),
		 "RC for %s", name);
	snprintf(adap->input_phys, sizeof(adap->input_phys),
		 "%s/input0", name);

	adap->rc->input_name = adap->input_name;
	adap->rc->input_phys = adap->input_phys;
	adap->rc->input_id.bustype = BUS_CEC;
	adap->rc->input_id.vendor = 0;
	adap->rc->input_id.product = 0;
	adap->rc->input_id.version = 1;
	adap->rc->driver_name = CEC_NAME;
	adap->rc->allowed_protocols = RC_BIT_CEC;
	adap->rc->priv = adap;
	adap->rc->map_name = RC_MAP_CEC;
	adap->rc->timeout = MS_TO_NS(100);
#else
	adap->capabilities &= ~CEC_CAP_RC;
#endif
	return adap;
}
Beispiel #21
0
static int __devinit iguanair_probe(struct usb_interface *intf,
						const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct iguanair *ir;
	struct rc_dev *rc;
	int ret, pipein, pipeout;
	struct usb_host_interface *idesc;

	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
	rc = rc_allocate_device();
	if (!ir || !rc) {
		ret = -ENOMEM;
		goto out;
	}

	ir->buf_in = usb_alloc_coherent(udev, MAX_IN_PACKET, GFP_KERNEL,
								&ir->dma_in);
	ir->packet = usb_alloc_coherent(udev, MAX_OUT_PACKET, GFP_KERNEL,
								&ir->dma_out);
	ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);
	ir->urb_out = usb_alloc_urb(0, GFP_KERNEL);

	if (!ir->buf_in || !ir->packet || !ir->urb_in || !ir->urb_out) {
		ret = -ENOMEM;
		goto out;
	}

	idesc = intf->altsetting;

	if (idesc->desc.bNumEndpoints < 2) {
		ret = -ENODEV;
		goto out;
	}

	ir->rc = rc;
	ir->dev = &intf->dev;
	ir->udev = udev;
	mutex_init(&ir->lock);

	init_completion(&ir->completion);
	pipeout = usb_sndintpipe(udev,
				idesc->endpoint[1].desc.bEndpointAddress);
	usb_fill_int_urb(ir->urb_out, udev, pipeout, ir->packet, MAX_OUT_PACKET,
						iguanair_irq_out, ir, 1);
	ir->urb_out->transfer_dma = ir->dma_out;
	ir->urb_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	pipein = usb_rcvintpipe(udev, idesc->endpoint[0].desc.bEndpointAddress);
	usb_fill_int_urb(ir->urb_in, udev, pipein, ir->buf_in, MAX_IN_PACKET,
							 iguanair_rx, ir, 1);
	ir->urb_in->transfer_dma = ir->dma_in;
	ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	ret = usb_submit_urb(ir->urb_in, GFP_KERNEL);
	if (ret) {
		dev_warn(&intf->dev, "failed to submit urb: %d\n", ret);
		goto out;
	}

	ret = iguanair_get_features(ir);
	if (ret)
		goto out2;

	snprintf(ir->name, sizeof(ir->name),
		"IguanaWorks USB IR Transceiver version 0x%04x", ir->version);

	usb_make_path(ir->udev, ir->phys, sizeof(ir->phys));

	rc->input_name = ir->name;
	rc->input_phys = ir->phys;
	usb_to_input_id(ir->udev, &rc->input_id);
	rc->dev.parent = &intf->dev;
	rc->driver_type = RC_DRIVER_IR_RAW;
	rc->allowed_protos = RC_BIT_ALL;
	rc->priv = ir;
	rc->open = iguanair_open;
	rc->close = iguanair_close;
	rc->s_tx_mask = iguanair_set_tx_mask;
	rc->s_tx_carrier = iguanair_set_tx_carrier;
	rc->tx_ir = iguanair_tx;
	rc->driver_name = DRIVER_NAME;
	rc->map_name = RC_MAP_RC6_MCE;
	rc->timeout = MS_TO_NS(100);
	rc->rx_resolution = RX_RESOLUTION;

	iguanair_set_tx_carrier(rc, 38000);

	ret = rc_register_device(rc);
	if (ret < 0) {
		dev_err(&intf->dev, "failed to register rc device %d", ret);
		goto out2;
	}

	usb_set_intfdata(intf, ir);

	return 0;
out2:
	usb_kill_urb(ir->urb_in);
	usb_kill_urb(ir->urb_out);
out:
	if (ir) {
		usb_free_urb(ir->urb_in);
		usb_free_urb(ir->urb_out);
		usb_free_coherent(udev, MAX_IN_PACKET, ir->buf_in, ir->dma_in);
		usb_free_coherent(udev, MAX_OUT_PACKET, ir->packet,
								ir->dma_out);
	}
	rc_free_device(rc);
	kfree(ir);
	return ret;
}
/*==========================================================================*
 * FUNCTION : Sem_Wait
 * PURPOSE  : 
 * CALLS    : 
 * CALLED BY: 
 * ARGUMENTS: IN HANDLE  hSem          : 
 *            IN DWORD   dwWaitTimeout : 
 * RETURN   : int : 
 * COMMENTS : 
 *==========================================================================*/
int Sem_Wait(IN HANDLE hSem, IN DWORD dwWaitTimeout)
{
	SEMAPHORE	*pSem = (SEMAPHORE *)hSem;
	struct	timespec ts;
	long	nWaitSeconds, nWaitNonaseconds;
	time_t	tmEndTime;
	
	if (hSem == NULL)
	{
		return ERR_INVALID_ARGS;
	}

	nWaitSeconds		= (long)MS_TO_SEC(dwWaitTimeout);			// sec
	nWaitNonaseconds	= (long)MS_TO_NS(dwWaitTimeout%MS_PER_SEC);	// nonasec

	clock_gettime(CLOCK_REALTIME, &ts);	// get the start time.
	
	ts.tv_nsec += nWaitNonaseconds;
	if (ts.tv_nsec > NS_PER_SEC)
	{
		ts.tv_sec  += 1;
		ts.tv_nsec -= NS_PER_SEC;
	}

	tmEndTime = ts.tv_sec;

#ifdef _DEBUG_MUTEX
	TRACE("[Sem_Wait] -- %p wait %d ms at %d\n", 
		RunThread_GetId(NULL), (int)dwWaitTimeout, (int)tmEndTime);
#endif //_DEBUG_MUTEX

	while (nWaitSeconds >= 0)
	{
		// get the end of the real time.
		tmEndTime += ((nWaitSeconds < MAX_WAIT_INTERVAL) ? nWaitSeconds
			: MAX_WAIT_INTERVAL);

		ts.tv_sec = tmEndTime;
		// do NOT change ts.tv_nsec.

		if (sem_timedwait(&pSem->hInternalSem, &ts) == 0)
		{
			return ERR_MUTEX_OK;//wait ok
		}

		//continue to try to wait.
		nWaitSeconds -= MAX_WAIT_INTERVAL;
		if (nWaitSeconds >= 0)
		{
			RUN_THREAD_HEARTBEAT();
		}
	}

#ifdef _DEBUG_MUTEX
	TRACE("[Sem_Wait] -- wait timeouted at %d\n", 
		(int)time(NULL));
#endif //_DEBUG_MUTEX

	// if goes here, timeout on trying to lock.
	return ERR_MUTEX_TIMEOUT;
}
Beispiel #23
0
static int meson_ir_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	struct resource *res;
	const char *map_name;
	struct meson_ir *ir;
	int ret;

	ir = devm_kzalloc(dev, sizeof(struct meson_ir), GFP_KERNEL);
	if (!ir)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	ir->reg = devm_ioremap_resource(dev, res);
	if (IS_ERR(ir->reg)) {
		dev_err(dev, "failed to map registers\n");
		return PTR_ERR(ir->reg);
	}

	ir->irq = platform_get_irq(pdev, 0);
	if (ir->irq < 0) {
		dev_err(dev, "no irq resource\n");
		return ir->irq;
	}

	ir->rc = rc_allocate_device();
	if (!ir->rc) {
		dev_err(dev, "failed to allocate rc device\n");
		return -ENOMEM;
	}

	ir->rc->priv = ir;
	ir->rc->input_name = DRIVER_NAME;
	ir->rc->input_phys = DRIVER_NAME "/input0";
	ir->rc->input_id.bustype = BUS_HOST;
	map_name = of_get_property(node, "linux,rc-map-name", NULL);
	ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY;
	ir->rc->dev.parent = dev;
	ir->rc->driver_type = RC_DRIVER_IR_RAW;
	ir->rc->allowed_protocols = RC_BIT_ALL;
	ir->rc->rx_resolution = US_TO_NS(MESON_TRATE);
	ir->rc->timeout = MS_TO_NS(200);
	ir->rc->driver_name = DRIVER_NAME;

	spin_lock_init(&ir->lock);
	platform_set_drvdata(pdev, ir);

	ret = rc_register_device(ir->rc);
	if (ret) {
		dev_err(dev, "failed to register rc device\n");
		goto out_free;
	}

	ret = devm_request_irq(dev, ir->irq, meson_ir_irq, 0, "ir-meson", ir);
	if (ret) {
		dev_err(dev, "failed to request irq\n");
		goto out_unreg;
	}

	/* Reset the decoder */
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, REG1_RESET);
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_RESET, 0);
	/* Set general operation mode */
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_MODE_MASK, REG1_MODE_GENERAL);
	/* Set rate */
	meson_ir_set_mask(ir, IR_DEC_REG0, REG0_RATE_MASK, MESON_TRATE - 1);
	/* IRQ on rising and falling edges */
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_IRQSEL_MASK,
			  REG1_IRQSEL_RISE_FALL);
	/* Enable the decoder */
	meson_ir_set_mask(ir, IR_DEC_REG1, REG1_ENABLE, REG1_ENABLE);

	dev_info(dev, "receiver initialized\n");

	return 0;
out_unreg:
	rc_unregister_device(ir->rc);
	ir->rc = NULL;
out_free:
	rc_free_device(ir->rc);

	return ret;
}
Beispiel #24
-1
static int igorplugusb_probe(struct usb_interface *intf,
					const struct usb_device_id *id)
{
	struct usb_device *udev;
	struct usb_host_interface *idesc;
	struct usb_endpoint_descriptor *ep;
	struct igorplugusb *ir;
	struct rc_dev *rc;
	int ret = -ENOMEM;

	udev = interface_to_usbdev(intf);
	idesc = intf->cur_altsetting;

	if (idesc->desc.bNumEndpoints != 1) {
		dev_err(&intf->dev, "incorrect number of endpoints");
		return -ENODEV;
	}

	ep = &idesc->endpoint[0].desc;
	if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_control(ep)) {
		dev_err(&intf->dev, "endpoint incorrect");
		return -ENODEV;
	}

	ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL);
	if (!ir)
		return -ENOMEM;

	ir->dev = &intf->dev;

	setup_timer(&ir->timer, igorplugusb_timer, (unsigned long)ir);

	ir->request.bRequest = GET_INFRACODE;
	ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN;
	ir->request.wLength = cpu_to_le16(sizeof(ir->buf_in));

	ir->urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!ir->urb)
		goto fail;

	usb_fill_control_urb(ir->urb, udev,
		usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request,
		ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir);

	usb_make_path(udev, ir->phys, sizeof(ir->phys));

	rc = rc_allocate_device(RC_DRIVER_IR_RAW);
	if (!rc)
		goto fail;

	rc->device_name = DRIVER_DESC;
	rc->input_phys = ir->phys;
	usb_to_input_id(udev, &rc->input_id);
	rc->dev.parent = &intf->dev;
	/*
	 * This device can only store 36 pulses + spaces, which is not enough
	 * for the NEC protocol and many others.
	 */
	rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER &
		~(RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 |
		  RC_PROTO_BIT_RC6_6A_20 | RC_PROTO_BIT_RC6_6A_24 |
		  RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE |
		  RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_SANYO);

	rc->priv = ir;
	rc->driver_name = DRIVER_NAME;
	rc->map_name = RC_MAP_HAUPPAUGE;
	rc->timeout = MS_TO_NS(100);
	rc->rx_resolution = 85333;

	ir->rc = rc;
	ret = rc_register_device(rc);
	if (ret) {
		dev_err(&intf->dev, "failed to register rc device: %d", ret);
		goto fail;
	}

	usb_set_intfdata(intf, ir);

	igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY);

	return 0;
fail:
	rc_free_device(ir->rc);
	usb_free_urb(ir->urb);
	del_timer(&ir->timer);

	return ret;
}