18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/* DVB USB compliant Linux driver for the
38c2ecf20Sopenharmony_ci *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
68c2ecf20Sopenharmony_ci * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Thanks to GENPIX for the sample code used to implement this module.
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * This module is based off the vp7045 and vp702x modules
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci#include "gp8psk.h"
158c2ecf20Sopenharmony_ci#include "gp8psk-fe.h"
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci/* debug */
188c2ecf20Sopenharmony_cistatic char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
198c2ecf20Sopenharmony_ciint dvb_usb_gp8psk_debug;
208c2ecf20Sopenharmony_cimodule_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
218c2ecf20Sopenharmony_ciMODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistruct gp8psk_state {
268c2ecf20Sopenharmony_ci	unsigned char data[80];
278c2ecf20Sopenharmony_ci};
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
308c2ecf20Sopenharmony_ci			    u16 index, u8 *b, int blen)
318c2ecf20Sopenharmony_ci{
328c2ecf20Sopenharmony_ci	struct gp8psk_state *st = d->priv;
338c2ecf20Sopenharmony_ci	int ret = 0,try = 0;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	if (blen > sizeof(st->data))
368c2ecf20Sopenharmony_ci		return -EIO;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
398c2ecf20Sopenharmony_ci		return ret;
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	while (ret >= 0 && ret != blen && try < 3) {
428c2ecf20Sopenharmony_ci		ret = usb_control_msg(d->udev,
438c2ecf20Sopenharmony_ci			usb_rcvctrlpipe(d->udev,0),
448c2ecf20Sopenharmony_ci			req,
458c2ecf20Sopenharmony_ci			USB_TYPE_VENDOR | USB_DIR_IN,
468c2ecf20Sopenharmony_ci			value, index, st->data, blen,
478c2ecf20Sopenharmony_ci			2000);
488c2ecf20Sopenharmony_ci		deb_info("reading number %d (ret: %d)\n",try,ret);
498c2ecf20Sopenharmony_ci		try++;
508c2ecf20Sopenharmony_ci	}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	if (ret < 0 || ret != blen) {
538c2ecf20Sopenharmony_ci		warn("usb in %d operation failed.", req);
548c2ecf20Sopenharmony_ci		ret = -EIO;
558c2ecf20Sopenharmony_ci	} else {
568c2ecf20Sopenharmony_ci		ret = 0;
578c2ecf20Sopenharmony_ci		memcpy(b, st->data, blen);
588c2ecf20Sopenharmony_ci	}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
618c2ecf20Sopenharmony_ci	debug_dump(b,blen,deb_xfer);
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	mutex_unlock(&d->usb_mutex);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	return ret;
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistatic int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
698c2ecf20Sopenharmony_ci			     u16 index, u8 *b, int blen)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	struct gp8psk_state *st = d->priv;
728c2ecf20Sopenharmony_ci	int ret;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
758c2ecf20Sopenharmony_ci	debug_dump(b,blen,deb_xfer);
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	if (blen > sizeof(st->data))
788c2ecf20Sopenharmony_ci		return -EIO;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
818c2ecf20Sopenharmony_ci		return ret;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	memcpy(st->data, b, blen);
848c2ecf20Sopenharmony_ci	if (usb_control_msg(d->udev,
858c2ecf20Sopenharmony_ci			usb_sndctrlpipe(d->udev,0),
868c2ecf20Sopenharmony_ci			req,
878c2ecf20Sopenharmony_ci			USB_TYPE_VENDOR | USB_DIR_OUT,
888c2ecf20Sopenharmony_ci			value, index, st->data, blen,
898c2ecf20Sopenharmony_ci			2000) != blen) {
908c2ecf20Sopenharmony_ci		warn("usb out operation failed.");
918c2ecf20Sopenharmony_ci		ret = -EIO;
928c2ecf20Sopenharmony_ci	} else
938c2ecf20Sopenharmony_ci		ret = 0;
948c2ecf20Sopenharmony_ci	mutex_unlock(&d->usb_mutex);
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	return ret;
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	return gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6);
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	return gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1);
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistatic void gp8psk_info(struct dvb_usb_device *d)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci	u8 fpga_vers, fw_vers[6];
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	if (!gp8psk_get_fw_version(d, fw_vers))
1158c2ecf20Sopenharmony_ci		info("FW Version = %i.%02i.%i (0x%x)  Build %4i/%02i/%02i",
1168c2ecf20Sopenharmony_ci		fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
1178c2ecf20Sopenharmony_ci		2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
1188c2ecf20Sopenharmony_ci	else
1198c2ecf20Sopenharmony_ci		info("failed to get FW version");
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	if (!gp8psk_get_fpga_version(d, &fpga_vers))
1228c2ecf20Sopenharmony_ci		info("FPGA Version = %i", fpga_vers);
1238c2ecf20Sopenharmony_ci	else
1248c2ecf20Sopenharmony_ci		info("failed to get FPGA version");
1258c2ecf20Sopenharmony_ci}
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_cistatic int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
1288c2ecf20Sopenharmony_ci{
1298c2ecf20Sopenharmony_ci	int ret;
1308c2ecf20Sopenharmony_ci	const struct firmware *fw = NULL;
1318c2ecf20Sopenharmony_ci	const u8 *ptr;
1328c2ecf20Sopenharmony_ci	u8 *buf;
1338c2ecf20Sopenharmony_ci	if ((ret = request_firmware(&fw, bcm4500_firmware,
1348c2ecf20Sopenharmony_ci					&d->udev->dev)) != 0) {
1358c2ecf20Sopenharmony_ci		err("did not find the bcm4500 firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware",
1368c2ecf20Sopenharmony_ci			bcm4500_firmware,ret);
1378c2ecf20Sopenharmony_ci		return ret;
1388c2ecf20Sopenharmony_ci	}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	ret = -EINVAL;
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
1438c2ecf20Sopenharmony_ci		goto out_rel_fw;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware);
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	ptr = fw->data;
1488c2ecf20Sopenharmony_ci	buf = kmalloc(64, GFP_KERNEL);
1498c2ecf20Sopenharmony_ci	if (!buf) {
1508c2ecf20Sopenharmony_ci		ret = -ENOMEM;
1518c2ecf20Sopenharmony_ci		goto out_rel_fw;
1528c2ecf20Sopenharmony_ci	}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	while (ptr[0] != 0xff) {
1558c2ecf20Sopenharmony_ci		u16 buflen = ptr[0] + 4;
1568c2ecf20Sopenharmony_ci		if (ptr + buflen >= fw->data + fw->size) {
1578c2ecf20Sopenharmony_ci			err("failed to load bcm4500 firmware.");
1588c2ecf20Sopenharmony_ci			goto out_free;
1598c2ecf20Sopenharmony_ci		}
1608c2ecf20Sopenharmony_ci		if (buflen > 64) {
1618c2ecf20Sopenharmony_ci			err("firmware chunk size bigger than 64 bytes.");
1628c2ecf20Sopenharmony_ci			goto out_free;
1638c2ecf20Sopenharmony_ci		}
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci		memcpy(buf, ptr, buflen);
1668c2ecf20Sopenharmony_ci		if (dvb_usb_generic_write(d, buf, buflen)) {
1678c2ecf20Sopenharmony_ci			err("failed to load bcm4500 firmware.");
1688c2ecf20Sopenharmony_ci			goto out_free;
1698c2ecf20Sopenharmony_ci		}
1708c2ecf20Sopenharmony_ci		ptr += buflen;
1718c2ecf20Sopenharmony_ci	}
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	ret = 0;
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ciout_free:
1768c2ecf20Sopenharmony_ci	kfree(buf);
1778c2ecf20Sopenharmony_ciout_rel_fw:
1788c2ecf20Sopenharmony_ci	release_firmware(fw);
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	return ret;
1818c2ecf20Sopenharmony_ci}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_cistatic int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	u8 status = 0, buf;
1868c2ecf20Sopenharmony_ci	int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci	if (onoff) {
1898c2ecf20Sopenharmony_ci		gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
1908c2ecf20Sopenharmony_ci		if (! (status & bm8pskStarted)) {  /* started */
1918c2ecf20Sopenharmony_ci			if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
1928c2ecf20Sopenharmony_ci				gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
1938c2ecf20Sopenharmony_ci			if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
1948c2ecf20Sopenharmony_ci				return -EINVAL;
1958c2ecf20Sopenharmony_ci			gp8psk_info(d);
1968c2ecf20Sopenharmony_ci		}
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci		if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
1998c2ecf20Sopenharmony_ci			if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */
2008c2ecf20Sopenharmony_ci				if(gp8psk_load_bcm4500fw(d))
2018c2ecf20Sopenharmony_ci					return -EINVAL;
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci		if (! (status & bmIntersilOn)) /* LNB Power */
2048c2ecf20Sopenharmony_ci			if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
2058c2ecf20Sopenharmony_ci					&buf, 1))
2068c2ecf20Sopenharmony_ci				return -EINVAL;
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci		/* Set DVB mode to 1 */
2098c2ecf20Sopenharmony_ci		if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
2108c2ecf20Sopenharmony_ci			if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
2118c2ecf20Sopenharmony_ci				return -EINVAL;
2128c2ecf20Sopenharmony_ci		/* Abort possible TS (if previous tune crashed) */
2138c2ecf20Sopenharmony_ci		if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0))
2148c2ecf20Sopenharmony_ci			return -EINVAL;
2158c2ecf20Sopenharmony_ci	} else {
2168c2ecf20Sopenharmony_ci		/* Turn off LNB power */
2178c2ecf20Sopenharmony_ci		if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
2188c2ecf20Sopenharmony_ci			return -EINVAL;
2198c2ecf20Sopenharmony_ci		/* Turn off 8psk power */
2208c2ecf20Sopenharmony_ci		if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
2218c2ecf20Sopenharmony_ci			return -EINVAL;
2228c2ecf20Sopenharmony_ci		if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
2238c2ecf20Sopenharmony_ci			gp8psk_usb_out_op(d, CW3K_INIT, 0, 0, NULL, 0);
2248c2ecf20Sopenharmony_ci	}
2258c2ecf20Sopenharmony_ci	return 0;
2268c2ecf20Sopenharmony_ci}
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_cistatic int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	u8 buf;
2318c2ecf20Sopenharmony_ci	int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	deb_xfer("reloading firmware\n");
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	/* Turn off 8psk power */
2368c2ecf20Sopenharmony_ci	if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
2378c2ecf20Sopenharmony_ci		return -EINVAL;
2388c2ecf20Sopenharmony_ci	/* Turn On 8psk power */
2398c2ecf20Sopenharmony_ci	if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
2408c2ecf20Sopenharmony_ci		return -EINVAL;
2418c2ecf20Sopenharmony_ci	/* load BCM4500 firmware */
2428c2ecf20Sopenharmony_ci	if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
2438c2ecf20Sopenharmony_ci		if (gp8psk_load_bcm4500fw(d))
2448c2ecf20Sopenharmony_ci			return -EINVAL;
2458c2ecf20Sopenharmony_ci	return 0;
2468c2ecf20Sopenharmony_ci}
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_cistatic int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
2498c2ecf20Sopenharmony_ci{
2508c2ecf20Sopenharmony_ci	return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
2518c2ecf20Sopenharmony_ci}
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci/* Callbacks for gp8psk-fe.c */
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_cistatic int gp8psk_fe_in(void *priv, u8 req, u16 value,
2568c2ecf20Sopenharmony_ci			    u16 index, u8 *b, int blen)
2578c2ecf20Sopenharmony_ci{
2588c2ecf20Sopenharmony_ci	struct dvb_usb_device *d = priv;
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	return gp8psk_usb_in_op(d, req, value, index, b, blen);
2618c2ecf20Sopenharmony_ci}
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_cistatic int gp8psk_fe_out(void *priv, u8 req, u16 value,
2648c2ecf20Sopenharmony_ci			    u16 index, u8 *b, int blen)
2658c2ecf20Sopenharmony_ci{
2668c2ecf20Sopenharmony_ci	struct dvb_usb_device *d = priv;
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci	return gp8psk_usb_out_op(d, req, value, index, b, blen);
2698c2ecf20Sopenharmony_ci}
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_cistatic int gp8psk_fe_reload(void *priv)
2728c2ecf20Sopenharmony_ci{
2738c2ecf20Sopenharmony_ci	struct dvb_usb_device *d = priv;
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci	return gp8psk_bcm4500_reload(d);
2768c2ecf20Sopenharmony_ci}
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_cistatic const struct gp8psk_fe_ops gp8psk_fe_ops = {
2798c2ecf20Sopenharmony_ci	.in = gp8psk_fe_in,
2808c2ecf20Sopenharmony_ci	.out = gp8psk_fe_out,
2818c2ecf20Sopenharmony_ci	.reload = gp8psk_fe_reload,
2828c2ecf20Sopenharmony_ci};
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_cistatic int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
2858c2ecf20Sopenharmony_ci{
2868c2ecf20Sopenharmony_ci	struct dvb_usb_device *d = adap->dev;
2878c2ecf20Sopenharmony_ci	int id = le16_to_cpu(d->udev->descriptor.idProduct);
2888c2ecf20Sopenharmony_ci	int is_rev1;
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci	is_rev1 = (id == USB_PID_GENPIX_8PSK_REV_1_WARM) ? true : false;
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci	adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach,
2938c2ecf20Sopenharmony_ci					 &gp8psk_fe_ops, d, is_rev1);
2948c2ecf20Sopenharmony_ci	return 0;
2958c2ecf20Sopenharmony_ci}
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties gp8psk_properties;
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_cistatic int gp8psk_usb_probe(struct usb_interface *intf,
3008c2ecf20Sopenharmony_ci		const struct usb_device_id *id)
3018c2ecf20Sopenharmony_ci{
3028c2ecf20Sopenharmony_ci	int ret;
3038c2ecf20Sopenharmony_ci	struct usb_device *udev = interface_to_usbdev(intf);
3048c2ecf20Sopenharmony_ci	ret = dvb_usb_device_init(intf, &gp8psk_properties,
3058c2ecf20Sopenharmony_ci				  THIS_MODULE, NULL, adapter_nr);
3068c2ecf20Sopenharmony_ci	if (ret == 0) {
3078c2ecf20Sopenharmony_ci		info("found Genpix USB device pID = %x (hex)",
3088c2ecf20Sopenharmony_ci			le16_to_cpu(udev->descriptor.idProduct));
3098c2ecf20Sopenharmony_ci	}
3108c2ecf20Sopenharmony_ci	return ret;
3118c2ecf20Sopenharmony_ci}
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_cistatic struct usb_device_id gp8psk_usb_table [] = {
3148c2ecf20Sopenharmony_ci	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
3158c2ecf20Sopenharmony_ci	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
3168c2ecf20Sopenharmony_ci	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
3178c2ecf20Sopenharmony_ci	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
3188c2ecf20Sopenharmony_ci	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_2) },
3198c2ecf20Sopenharmony_ci/*	    { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */
3208c2ecf20Sopenharmony_ci	    { 0 },
3218c2ecf20Sopenharmony_ci};
3228c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_cistatic struct dvb_usb_device_properties gp8psk_properties = {
3258c2ecf20Sopenharmony_ci	.usb_ctrl = CYPRESS_FX2,
3268c2ecf20Sopenharmony_ci	.firmware = "dvb-usb-gp8psk-01.fw",
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci	.size_of_priv = sizeof(struct gp8psk_state),
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	.num_adapters = 1,
3318c2ecf20Sopenharmony_ci	.adapter = {
3328c2ecf20Sopenharmony_ci		{
3338c2ecf20Sopenharmony_ci		.num_frontends = 1,
3348c2ecf20Sopenharmony_ci		.fe = {{
3358c2ecf20Sopenharmony_ci			.streaming_ctrl   = gp8psk_streaming_ctrl,
3368c2ecf20Sopenharmony_ci			.frontend_attach  = gp8psk_frontend_attach,
3378c2ecf20Sopenharmony_ci			/* parameter for the MPEG2-data transfer */
3388c2ecf20Sopenharmony_ci			.stream = {
3398c2ecf20Sopenharmony_ci				.type = USB_BULK,
3408c2ecf20Sopenharmony_ci				.count = 7,
3418c2ecf20Sopenharmony_ci				.endpoint = 0x82,
3428c2ecf20Sopenharmony_ci				.u = {
3438c2ecf20Sopenharmony_ci					.bulk = {
3448c2ecf20Sopenharmony_ci						.buffersize = 8192,
3458c2ecf20Sopenharmony_ci					}
3468c2ecf20Sopenharmony_ci				}
3478c2ecf20Sopenharmony_ci			},
3488c2ecf20Sopenharmony_ci		}},
3498c2ecf20Sopenharmony_ci		}
3508c2ecf20Sopenharmony_ci	},
3518c2ecf20Sopenharmony_ci	.power_ctrl       = gp8psk_power_ctrl,
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci	.generic_bulk_ctrl_endpoint = 0x01,
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci	.num_device_descs = 4,
3568c2ecf20Sopenharmony_ci	.devices = {
3578c2ecf20Sopenharmony_ci		{ .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
3588c2ecf20Sopenharmony_ci		  .cold_ids = { &gp8psk_usb_table[0], NULL },
3598c2ecf20Sopenharmony_ci		  .warm_ids = { &gp8psk_usb_table[1], NULL },
3608c2ecf20Sopenharmony_ci		},
3618c2ecf20Sopenharmony_ci		{ .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver",
3628c2ecf20Sopenharmony_ci		  .cold_ids = { NULL },
3638c2ecf20Sopenharmony_ci		  .warm_ids = { &gp8psk_usb_table[2], NULL },
3648c2ecf20Sopenharmony_ci		},
3658c2ecf20Sopenharmony_ci		{ .name = "Genpix SkyWalker-1 DVB-S receiver",
3668c2ecf20Sopenharmony_ci		  .cold_ids = { NULL },
3678c2ecf20Sopenharmony_ci		  .warm_ids = { &gp8psk_usb_table[3], NULL },
3688c2ecf20Sopenharmony_ci		},
3698c2ecf20Sopenharmony_ci		{ .name = "Genpix SkyWalker-2 DVB-S receiver",
3708c2ecf20Sopenharmony_ci		  .cold_ids = { NULL },
3718c2ecf20Sopenharmony_ci		  .warm_ids = { &gp8psk_usb_table[4], NULL },
3728c2ecf20Sopenharmony_ci		},
3738c2ecf20Sopenharmony_ci		{ NULL },
3748c2ecf20Sopenharmony_ci	}
3758c2ecf20Sopenharmony_ci};
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci/* usb specific object needed to register this driver with the usb subsystem */
3788c2ecf20Sopenharmony_cistatic struct usb_driver gp8psk_usb_driver = {
3798c2ecf20Sopenharmony_ci	.name		= "dvb_usb_gp8psk",
3808c2ecf20Sopenharmony_ci	.probe		= gp8psk_usb_probe,
3818c2ecf20Sopenharmony_ci	.disconnect = dvb_usb_device_exit,
3828c2ecf20Sopenharmony_ci	.id_table	= gp8psk_usb_table,
3838c2ecf20Sopenharmony_ci};
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_cimodule_usb_driver(gp8psk_usb_driver);
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ciMODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
3888c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Driver for Genpix DVB-S");
3898c2ecf20Sopenharmony_ciMODULE_VERSION("1.1");
3908c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
391