/*
 * Copyright (C) 2008 Sensoray Company Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (Version 2) as
 * published by the Free Software Foundation.
 *
 * 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.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <dvb-usb.h>

#define S2250_LOADER_FIRMWARE	"s2250_loader.fw"
#define S2250_FIRMWARE		"s2250.fw"

typedef struct device_extension_s {
    struct kref     kref;
    int minor;
    struct usb_device *usbdev;
} device_extension_t, *pdevice_extension_t;

#define USB_s2250loader_MAJOR 240
#define USB_s2250loader_MINOR_BASE 0
#define MAX_DEVICES 256

static pdevice_extension_t s2250_dev_table[MAX_DEVICES];
static DEFINE_MUTEX(s2250_dev_table_mutex);

#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref)
static void s2250loader_delete(struct kref *kref)
{
	pdevice_extension_t s = to_s2250loader_dev_common(kref);
	s2250_dev_table[s->minor] = NULL;
	kfree(s);
}

static int s2250loader_probe(struct usb_interface *interface,
				const struct usb_device_id *id)
{
	struct usb_device *usbdev;
	int minor, ret;
	pdevice_extension_t s = NULL;
	const struct firmware *fw;

	usbdev = usb_get_dev(interface_to_usbdev(interface));
	if (!usbdev) {
		printk(KERN_ERR "Enter s2250loader_probe failed\n");
		return -1;
	}
	printk(KERN_INFO "Enter s2250loader_probe 2.6 kernel\n");
	printk(KERN_INFO "vendor id 0x%x, device id 0x%x devnum:%d\n",
	   usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
	   usbdev->devnum);

	if (usbdev->descriptor.bNumConfigurations != 1) {
		printk(KERN_ERR "can't handle multiple config\n");
		return -1;
	}
	mutex_lock(&s2250_dev_table_mutex);

	for (minor = 0; minor < MAX_DEVICES; minor++) {
		if (s2250_dev_table[minor] == NULL)
			break;
	}

	if (minor < 0 || minor >= MAX_DEVICES) {
		printk(KERN_ERR "Invalid minor: %d\n", minor);
		goto failed;
	}

	/* Allocate dev data structure */
	s = kmalloc(sizeof(device_extension_t), GFP_KERNEL);
	if (s == NULL) {
		printk(KERN_ERR "Out of memory\n");
		goto failed;
	}
	s2250_dev_table[minor] = s;

	printk(KERN_INFO "s2250loader_probe: Device %d on Bus %d Minor %d\n",
		usbdev->devnum, usbdev->bus->busnum, minor);

	memset(s, 0, sizeof(device_extension_t));
	s->usbdev = usbdev;
	printk(KERN_INFO "loading 2250 loader\n");

	kref_init(&(s->kref));

	mutex_unlock(&s2250_dev_table_mutex);

	if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
		printk(KERN_ERR
			"s2250: unable to load firmware from file \"%s\"\n",
			S2250_LOADER_FIRMWARE);
		goto failed2;
	}
	ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
	release_firmware(fw);
	if (0 != ret) {
		printk(KERN_ERR "loader download failed\n");
		goto failed2;
	}

	if (request_firmware(&fw, S2250_FIRMWARE, &usbdev->dev)) {
		printk(KERN_ERR
			"s2250: unable to load firmware from file \"%s\"\n",
			S2250_FIRMWARE);
		goto failed2;
	}
	ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
	release_firmware(fw);
	if (0 != ret) {
		printk(KERN_ERR "firmware_s2250 download failed\n");
		goto failed2;
	}

	usb_set_intfdata(interface, s);
	return 0;

failed:
	mutex_unlock(&s2250_dev_table_mutex);
failed2:
	if (s)
		kref_put(&(s->kref), s2250loader_delete);

	printk(KERN_ERR "probe failed\n");
	return -1;
}

static void s2250loader_disconnect(struct usb_interface *interface)
{
	pdevice_extension_t s;
	printk(KERN_INFO "s2250: disconnect\n");
	lock_kernel();
	s = usb_get_intfdata(interface);
	usb_set_intfdata(interface, NULL);
	kref_put(&(s->kref), s2250loader_delete);
	unlock_kernel();
}

static const struct usb_device_id s2250loader_ids[] = {
	{USB_DEVICE(0x1943, 0xa250)},
	{}                          /* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, s2250loader_ids);

static struct usb_driver s2250loader_driver = {
	.name		= "s2250-loader",
	.probe		= s2250loader_probe,
	.disconnect	= s2250loader_disconnect,
	.id_table	= s2250loader_ids,
};

static int __init s2250loader_init(void)
{
	int r;
	unsigned i = 0;

	for (i = 0; i < MAX_DEVICES; i++)
		s2250_dev_table[i] = NULL;

	r = usb_register(&s2250loader_driver);
	if (r) {
		printk(KERN_ERR "usb_register failed. Error number %d\n", r);
		return -1;
	}

	printk(KERN_INFO "s2250loader_init: driver registered\n");
	return 0;
}
module_init(s2250loader_init);

static void __exit s2250loader_cleanup(void)
{
	printk(KERN_INFO "s2250loader_cleanup\n");
	usb_deregister(&s2250loader_driver);
}
module_exit(s2250loader_cleanup);

MODULE_AUTHOR("");
MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251");
MODULE_LICENSE("GPL v2");
