/*
 *      uvc_status.c  --  USB Video Class driver - Status endpoint
 *
 *      Copyright (C) 2005-2009
 *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 */

#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/input.h>

#include "uvcvideo.h"

/* --------------------------------------------------------------------------
 * Input device
 */
#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
static int uvc_input_init(struct uvc_device *dev)
{
	struct input_dev *input;
	int ret;

	input = input_allocate_device();
	if (input == NULL)
		return -ENOMEM;

	usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
	strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));

	input->name = dev->name;
	input->phys = dev->input_phys;
	usb_to_input_id(dev->udev, &input->id);
	input->dev.parent = &dev->intf->dev;

	__set_bit(EV_KEY, input->evbit);
	__set_bit(KEY_CAMERA, input->keybit);

	if ((ret = input_register_device(input)) < 0)
		goto error;

	dev->input = input;
	return 0;

error:
	input_free_device(input);
	return ret;
}

static void uvc_input_unregister(struct uvc_device *dev)
{
	if (dev->input)
		input_unregister_device(dev->input);
}

static void uvc_input_report_key(struct uvc_device *dev, unsigned int code,
	int value)
{
	if (dev->input) {
		input_report_key(dev->input, code, value);
		input_sync(dev->input);
	}
}

#else
#define uvc_input_init(dev)
#define uvc_input_unregister(dev)
#define uvc_input_report_key(dev, code, value)
#endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */

/* --------------------------------------------------------------------------
 * Status interrupt endpoint
 */
struct uvc_streaming_status {
	u8	bStatusType;
	u8	bOriginator;
	u8	bEvent;
	u8	bValue[];
} __packed;

struct uvc_control_status {
	u8	bStatusType;
	u8	bOriginator;
	u8	bEvent;
	u8	bSelector;
	u8	bAttribute;
	u8	bValue[];
} __packed;

static void uvc_event_streaming(struct uvc_device *dev,
				struct uvc_streaming_status *status, int len)
{
	if (len < 3) {
		uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event "
				"received.\n");
		return;
	}

	if (status->bEvent == 0) {
		if (len < 4)
			return;
		uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n",
			  status->bOriginator,
			  status->bValue[0] ? "pressed" : "released", len);
		uvc_input_report_key(dev, KEY_CAMERA, status->bValue[0]);
	} else {
		uvc_trace(UVC_TRACE_STATUS,
			  "Stream %u error event %02x len %d.\n",
			  status->bOriginator, status->bEvent, len);
	}
}

#define UVC_CTRL_VALUE_CHANGE	0
#define UVC_CTRL_INFO_CHANGE	1
#define UVC_CTRL_FAILURE_CHANGE	2
#define UVC_CTRL_MIN_CHANGE	3
#define UVC_CTRL_MAX_CHANGE	4

static struct uvc_control *uvc_event_entity_find_ctrl(struct uvc_entity *entity,
						      u8 selector)
{
	struct uvc_control *ctrl;
	unsigned int i;

	for (i = 0, ctrl = entity->controls; i < entity->ncontrols; i++, ctrl++)
		if (ctrl->info.selector == selector)
			return ctrl;

	return NULL;
}

static struct uvc_control *uvc_event_find_ctrl(struct uvc_device *dev,
					const struct uvc_control_status *status,
					struct uvc_video_chain **chain)
{
	list_for_each_entry((*chain), &dev->chains, list) {
		struct uvc_entity *entity;
		struct uvc_control *ctrl;

		list_for_each_entry(entity, &(*chain)->entities, chain) {
			if (entity->id != status->bOriginator)
				continue;

			ctrl = uvc_event_entity_find_ctrl(entity,
							  status->bSelector);
			if (ctrl)
				return ctrl;
		}
	}

	return NULL;
}

static bool uvc_event_control(struct urb *urb,
			      const struct uvc_control_status *status, int len)
{
	static const char *attrs[] = { "value", "info", "failure", "min", "max" };
	struct uvc_device *dev = urb->context;
	struct uvc_video_chain *chain;
	struct uvc_control *ctrl;

	if (len < 6 || status->bEvent != 0 ||
	    status->bAttribute >= ARRAY_SIZE(attrs)) {
		uvc_trace(UVC_TRACE_STATUS, "Invalid control status event "
				"received.\n");
		return false;
	}

	uvc_trace(UVC_TRACE_STATUS, "Control %u/%u %s change len %d.\n",
		  status->bOriginator, status->bSelector,
		  attrs[status->bAttribute], len);

	/* Find the control. */
	ctrl = uvc_event_find_ctrl(dev, status, &chain);
	if (!ctrl)
		return false;

	switch (status->bAttribute) {
	case UVC_CTRL_VALUE_CHANGE:
		return uvc_ctrl_status_event(urb, chain, ctrl, status->bValue);

	case UVC_CTRL_INFO_CHANGE:
	case UVC_CTRL_FAILURE_CHANGE:
	case UVC_CTRL_MIN_CHANGE:
	case UVC_CTRL_MAX_CHANGE:
		break;
	}

	return false;
}

static void uvc_status_complete(struct urb *urb)
{
	struct uvc_device *dev = urb->context;
	int len, ret;

	switch (urb->status) {
	case 0:
		break;

	case -ENOENT:		/* usb_kill_urb() called. */
	case -ECONNRESET:	/* usb_unlink_urb() called. */
	case -ESHUTDOWN:	/* The endpoint is being disabled. */
	case -EPROTO:		/* Device is disconnected (reported by some
				 * host controller). */
		return;

	default:
		uvc_printk(KERN_WARNING, "Non-zero status (%d) in status "
			"completion handler.\n", urb->status);
		return;
	}

	len = urb->actual_length;
	if (len > 0) {
		switch (dev->status[0] & 0x0f) {
		case UVC_STATUS_TYPE_CONTROL: {
			struct uvc_control_status *status =
				(struct uvc_control_status *)dev->status;

			if (uvc_event_control(urb, status, len))
				/* The URB will be resubmitted in work context. */
				return;
			break;
		}

		case UVC_STATUS_TYPE_STREAMING: {
			struct uvc_streaming_status *status =
				(struct uvc_streaming_status *)dev->status;

			uvc_event_streaming(dev, status, len);
			break;
		}

		default:
			uvc_trace(UVC_TRACE_STATUS, "Unknown status event "
				"type %u.\n", dev->status[0]);
			break;
		}
	}

	/* Resubmit the URB. */
	urb->interval = dev->int_ep->desc.bInterval;
	if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
		uvc_printk(KERN_ERR, "Failed to resubmit status URB (%d).\n",
			ret);
	}
}

int uvc_status_init(struct uvc_device *dev)
{
	struct usb_host_endpoint *ep = dev->int_ep;
	unsigned int pipe;
	int interval;

	if (ep == NULL)
		return 0;

	uvc_input_init(dev);

	dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL);
	if (dev->status == NULL)
		return -ENOMEM;

	dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (dev->int_urb == NULL) {
		kfree(dev->status);
		return -ENOMEM;
	}

	pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);

	/* For high-speed interrupt endpoints, the bInterval value is used as
	 * an exponent of two. Some developers forgot about it.
	 */
	interval = ep->desc.bInterval;
	if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH &&
	    (dev->quirks & UVC_QUIRK_STATUS_INTERVAL))
		interval = fls(interval) - 1;

	usb_fill_int_urb(dev->int_urb, dev->udev, pipe,
		dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete,
		dev, interval);

	return 0;
}

void uvc_status_unregister(struct uvc_device *dev)
{
	usb_kill_urb(dev->int_urb);
	uvc_input_unregister(dev);
}

void uvc_status_cleanup(struct uvc_device *dev)
{
	usb_free_urb(dev->int_urb);
	kfree(dev->status);
}

int uvc_status_start(struct uvc_device *dev, gfp_t flags)
{
	if (dev->int_urb == NULL)
		return 0;

	return usb_submit_urb(dev->int_urb, flags);
}

void uvc_status_stop(struct uvc_device *dev)
{
	usb_kill_urb(dev->int_urb);
}
