/*
 * Copyright (c) 2012 Hans Verkuil <hverkuil@xs4all.nl>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/* kernel includes */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <linux/usb.h>
#include <linux/mutex.h>

/* driver and module definitions */
MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
MODULE_DESCRIPTION("Keene FM Transmitter driver");
MODULE_LICENSE("GPL");

/* Actually, it advertises itself as a Logitech */
#define USB_KEENE_VENDOR 0x046d
#define USB_KEENE_PRODUCT 0x0a0e

/* Probably USB_TIMEOUT should be modified in module parameter */
#define BUFFER_LENGTH 8
#define USB_TIMEOUT 500

/* Frequency limits in MHz */
#define FREQ_MIN  76U
#define FREQ_MAX 108U
#define FREQ_MUL 16000U

/* USB Device ID List */
static struct usb_device_id usb_keene_device_table[] = {
	{USB_DEVICE_AND_INTERFACE_INFO(USB_KEENE_VENDOR, USB_KEENE_PRODUCT,
							USB_CLASS_HID, 0, 0) },
	{ }						/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, usb_keene_device_table);

struct keene_device {
	struct usb_device *usbdev;
	struct usb_interface *intf;
	struct video_device vdev;
	struct v4l2_device v4l2_dev;
	struct v4l2_ctrl_handler hdl;
	struct mutex lock;

	u8 *buffer;
	unsigned curfreq;
	u8 tx;
	u8 pa;
	bool stereo;
	bool muted;
	bool preemph_75_us;
};

static inline struct keene_device *to_keene_dev(struct v4l2_device *v4l2_dev)
{
	return container_of(v4l2_dev, struct keene_device, v4l2_dev);
}

/* Set frequency (if non-0), PA, mute and turn on/off the FM transmitter. */
static int keene_cmd_main(struct keene_device *radio, unsigned freq, bool play)
{
	unsigned short freq_send = freq ? (freq - 76 * 16000) / 800 : 0;
	int ret;

	radio->buffer[0] = 0x00;
	radio->buffer[1] = 0x50;
	radio->buffer[2] = (freq_send >> 8) & 0xff;
	radio->buffer[3] = freq_send & 0xff;
	radio->buffer[4] = radio->pa;
	/* If bit 4 is set, then tune to the frequency.
	   If bit 3 is set, then unmute; if bit 2 is set, then mute.
	   If bit 1 is set, then enter idle mode; if bit 0 is set,
	   then enter transmit mode.
	 */
	radio->buffer[5] = (radio->muted ? 4 : 8) | (play ? 1 : 2) |
							(freq ? 0x10 : 0);
	radio->buffer[6] = 0x00;
	radio->buffer[7] = 0x00;

	ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
		9, 0x21, 0x200, 2, radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);

	if (ret < 0) {
		dev_warn(&radio->vdev.dev, "%s failed (%d)\n", __func__, ret);
		return ret;
	}
	if (freq)
		radio->curfreq = freq;
	return 0;
}

/* Set TX, stereo and preemphasis mode (50 us vs 75 us). */
static int keene_cmd_set(struct keene_device *radio)
{
	int ret;

	radio->buffer[0] = 0x00;
	radio->buffer[1] = 0x51;
	radio->buffer[2] = radio->tx;
	/* If bit 0 is set, then transmit mono, otherwise stereo.
	   If bit 2 is set, then enable 75 us preemphasis, otherwise
	   it is 50 us. */
	radio->buffer[3] = (radio->stereo ? 0 : 1) | (radio->preemph_75_us ? 4 : 0);
	radio->buffer[4] = 0x00;
	radio->buffer[5] = 0x00;
	radio->buffer[6] = 0x00;
	radio->buffer[7] = 0x00;

	ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
		9, 0x21, 0x200, 2, radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);

	if (ret < 0) {
		dev_warn(&radio->vdev.dev, "%s failed (%d)\n", __func__, ret);
		return ret;
	}
	return 0;
}

/* Handle unplugging the device.
 * We call video_unregister_device in any case.
 * The last function called in this procedure is
 * usb_keene_device_release.
 */
static void usb_keene_disconnect(struct usb_interface *intf)
{
	struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));

	mutex_lock(&radio->lock);
	usb_set_intfdata(intf, NULL);
	video_unregister_device(&radio->vdev);
	v4l2_device_disconnect(&radio->v4l2_dev);
	mutex_unlock(&radio->lock);
	v4l2_device_put(&radio->v4l2_dev);
}

static int usb_keene_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));

	return keene_cmd_main(radio, 0, false);
}

static int usb_keene_resume(struct usb_interface *intf)
{
	struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));

	mdelay(50);
	keene_cmd_set(radio);
	keene_cmd_main(radio, radio->curfreq, true);
	return 0;
}

static int vidioc_querycap(struct file *file, void *priv,
					struct v4l2_capability *v)
{
	struct keene_device *radio = video_drvdata(file);

	strlcpy(v->driver, "radio-keene", sizeof(v->driver));
	strlcpy(v->card, "Keene FM Transmitter", sizeof(v->card));
	usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
	v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_MODULATOR;
	v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
	return 0;
}

static int vidioc_g_modulator(struct file *file, void *priv,
				struct v4l2_modulator *v)
{
	struct keene_device *radio = video_drvdata(file);

	if (v->index > 0)
		return -EINVAL;

	strlcpy(v->name, "FM", sizeof(v->name));
	v->rangelow = FREQ_MIN * FREQ_MUL;
	v->rangehigh = FREQ_MAX * FREQ_MUL;
	v->txsubchans = radio->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
	v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
	return 0;
}

static int vidioc_s_modulator(struct file *file, void *priv,
				const struct v4l2_modulator *v)
{
	struct keene_device *radio = video_drvdata(file);

	if (v->index > 0)
		return -EINVAL;

	radio->stereo = (v->txsubchans == V4L2_TUNER_SUB_STEREO);
	return keene_cmd_set(radio);
}

static int vidioc_s_frequency(struct file *file, void *priv,
				const struct v4l2_frequency *f)
{
	struct keene_device *radio = video_drvdata(file);
	unsigned freq = f->frequency;

	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
		return -EINVAL;
	freq = clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
	return keene_cmd_main(radio, freq, true);
}

static int vidioc_g_frequency(struct file *file, void *priv,
				struct v4l2_frequency *f)
{
	struct keene_device *radio = video_drvdata(file);

	if (f->tuner != 0)
		return -EINVAL;
	f->type = V4L2_TUNER_RADIO;
	f->frequency = radio->curfreq;
	return 0;
}

static int keene_s_ctrl(struct v4l2_ctrl *ctrl)
{
	static const u8 db2tx[] = {
	     /*	 -15,  -12,   -9,   -6,   -3,    0 dB */
		0x03, 0x13, 0x02, 0x12, 0x22, 0x32,
	     /*	   3,    6,    9,   12,   15,   18 dB */
		0x21, 0x31, 0x20, 0x30, 0x40, 0x50
	};
	struct keene_device *radio =
		container_of(ctrl->handler, struct keene_device, hdl);

	switch (ctrl->id) {
	case V4L2_CID_AUDIO_MUTE:
		radio->muted = ctrl->val;
		return keene_cmd_main(radio, 0, true);

	case V4L2_CID_TUNE_POWER_LEVEL:
		/* To go from dBuV to the register value we apply the
		   following formula: */
		radio->pa = (ctrl->val - 71) * 100 / 62;
		return keene_cmd_main(radio, 0, true);

	case V4L2_CID_TUNE_PREEMPHASIS:
		radio->preemph_75_us = ctrl->val == V4L2_PREEMPHASIS_75_uS;
		return keene_cmd_set(radio);

	case V4L2_CID_AUDIO_COMPRESSION_GAIN:
		radio->tx = db2tx[(ctrl->val - ctrl->minimum) / ctrl->step];
		return keene_cmd_set(radio);
	}
	return -EINVAL;
}

/* File system interface */
static const struct v4l2_file_operations usb_keene_fops = {
	.owner		= THIS_MODULE,
	.open           = v4l2_fh_open,
	.release        = v4l2_fh_release,
	.poll		= v4l2_ctrl_poll,
	.unlocked_ioctl	= video_ioctl2,
};

static const struct v4l2_ctrl_ops keene_ctrl_ops = {
	.s_ctrl = keene_s_ctrl,
};

static const struct v4l2_ioctl_ops usb_keene_ioctl_ops = {
	.vidioc_querycap    = vidioc_querycap,
	.vidioc_g_modulator = vidioc_g_modulator,
	.vidioc_s_modulator = vidioc_s_modulator,
	.vidioc_g_frequency = vidioc_g_frequency,
	.vidioc_s_frequency = vidioc_s_frequency,
	.vidioc_log_status = v4l2_ctrl_log_status,
	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};

static void usb_keene_video_device_release(struct v4l2_device *v4l2_dev)
{
	struct keene_device *radio = to_keene_dev(v4l2_dev);

	/* free rest memory */
	v4l2_ctrl_handler_free(&radio->hdl);
	kfree(radio->buffer);
	kfree(radio);
}

/* check if the device is present and register with v4l and usb if it is */
static int usb_keene_probe(struct usb_interface *intf,
				const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct keene_device *radio;
	struct v4l2_ctrl_handler *hdl;
	int retval = 0;

	/*
	 * The Keene FM transmitter USB device has the same USB ID as
	 * the Logitech AudioHub Speaker, but it should ignore the hid.
	 * Check if the name is that of the Keene device.
	 * If not, then someone connected the AudioHub and we shouldn't
	 * attempt to handle this driver.
	 * For reference: the product name of the AudioHub is
	 * "AudioHub Speaker".
	 */
	if (dev->product && strcmp(dev->product, "B-LINK USB Audio  "))
		return -ENODEV;

	radio = kzalloc(sizeof(struct keene_device), GFP_KERNEL);
	if (radio)
		radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);

	if (!radio || !radio->buffer) {
		dev_err(&intf->dev, "kmalloc for keene_device failed\n");
		kfree(radio);
		retval = -ENOMEM;
		goto err;
	}

	hdl = &radio->hdl;
	v4l2_ctrl_handler_init(hdl, 4);
	v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_AUDIO_MUTE,
			0, 1, 1, 0);
	v4l2_ctrl_new_std_menu(hdl, &keene_ctrl_ops, V4L2_CID_TUNE_PREEMPHASIS,
			V4L2_PREEMPHASIS_75_uS, 1, V4L2_PREEMPHASIS_50_uS);
	v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_TUNE_POWER_LEVEL,
			84, 118, 1, 118);
	v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_AUDIO_COMPRESSION_GAIN,
			-15, 18, 3, 0);
	radio->pa = 118;
	radio->tx = 0x32;
	radio->stereo = true;
	if (hdl->error) {
		retval = hdl->error;

		v4l2_ctrl_handler_free(hdl);
		goto err_v4l2;
	}
	retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
	if (retval < 0) {
		dev_err(&intf->dev, "couldn't register v4l2_device\n");
		goto err_v4l2;
	}

	mutex_init(&radio->lock);

	radio->v4l2_dev.ctrl_handler = hdl;
	radio->v4l2_dev.release = usb_keene_video_device_release;
	strlcpy(radio->vdev.name, radio->v4l2_dev.name,
		sizeof(radio->vdev.name));
	radio->vdev.v4l2_dev = &radio->v4l2_dev;
	radio->vdev.fops = &usb_keene_fops;
	radio->vdev.ioctl_ops = &usb_keene_ioctl_ops;
	radio->vdev.lock = &radio->lock;
	radio->vdev.release = video_device_release_empty;
	radio->vdev.vfl_dir = VFL_DIR_TX;

	radio->usbdev = interface_to_usbdev(intf);
	radio->intf = intf;
	usb_set_intfdata(intf, &radio->v4l2_dev);

	video_set_drvdata(&radio->vdev, radio);
	set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);

	/* at least 11ms is needed in order to settle hardware */
	msleep(20);
	keene_cmd_main(radio, 95.16 * FREQ_MUL, false);

	retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1);
	if (retval < 0) {
		dev_err(&intf->dev, "could not register video device\n");
		goto err_vdev;
	}
	v4l2_ctrl_handler_setup(hdl);
	dev_info(&intf->dev, "V4L2 device registered as %s\n",
			video_device_node_name(&radio->vdev));
	return 0;

err_vdev:
	v4l2_device_unregister(&radio->v4l2_dev);
err_v4l2:
	kfree(radio->buffer);
	kfree(radio);
err:
	return retval;
}

/* USB subsystem interface */
static struct usb_driver usb_keene_driver = {
	.name			= "radio-keene",
	.probe			= usb_keene_probe,
	.disconnect		= usb_keene_disconnect,
	.id_table		= usb_keene_device_table,
	.suspend		= usb_keene_suspend,
	.resume			= usb_keene_resume,
	.reset_resume		= usb_keene_resume,
};

static int __init keene_init(void)
{
	int retval = usb_register(&usb_keene_driver);

	if (retval)
		pr_err(KBUILD_MODNAME
			": usb_register failed. Error number %d\n", retval);

	return retval;
}

static void __exit keene_exit(void)
{
	usb_deregister(&usb_keene_driver);
}

module_init(keene_init);
module_exit(keene_exit);

