Re: [PATCH] Drivers for Pinnacle pctv200e and pctv60e

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Wed, 1 Apr 2009, Gabriele Dini Ciacci wrote:

On Tue, 31 Mar 2009 17:51:23 -0400
Devin Heitmueller <devin.heitmueller@xxxxxxxxx> wrote:

On Tue, Mar 31, 2009 at 5:35 PM, Gabriele Dini Ciacci
<dark.schneider@xxxxxx> wrote:
I it's so, say me how to make or where to look to create a profile
for the existing driver.

I am willing to do the work.

(when I first wrote the driver to me it seemed that this was the
simplet way.

Meanwhile I will try to look at the Cypress FX2

As Michael Krufky pointed out to me off-list, I was not exactly
correct here.

While there are indeed drivers based on the same FX2 chip in your
device, it may be possible to reuse an existing driver, or you may
need a whole new driver, depending on how much the firmware varies
between your product versus the others.  You may want to look at the
pvrusb2 and cxusb drivers, which also use the FX2 chip, and see what
similarities exist in terms of the API and command set.  If it is not
similar to any of the others, then writing a new driver is probably
the correct approach.

Regards,

Devin


Fine perfect, thanks,

Attached you can find my attempts from 2005. I2C should work, please re-use this implementation as it nicely splits i2c_transfer from the rest of the required functionality.

I think I still have the pctv 200e somewhere in a box... I may get it back, undust it and try.

Patrick.

--
  Mail: patrick.boettcher@xxxxxxx
  WWW:  http://www.wi-bw.tfh-wildau.de/~pboettch/
/* DVB USB compliant linux driver for the Pinnacle PCTV 200e DVB-T USB2.0 receiver.
 *
 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@xxxxxxx)
 *
 *  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, version 2.
 *
 * see Documentation/dvb/README.dvb-usb for more information
 */

#ifndef _DVB_USB_PCTV_H_
#define _DVB_USB_PCTV_H_

#define DVB_USB_LOG_PREFIX "pctv"
#include "dvb-usb.h"

extern int dvb_usb_pctv_debug;
#define deb_info(args...)   dprintk(dvb_usb_pctv_debug,0x01,args)

#define CMD_I2C_WRITE  0x01
/* out: <addr << 1> <olen> <buf>[olen]
 *  in: 0x00 */

#define CMD_I2C_READ   0x02
/* out: <addr << 1> <olen> <ilen> <buf>[olen]
 *  in: 0x00 <buf>[ilen] */

#define CMD_GPIO_TUNER 0x16
/* out: <onoff>
 *  in: 0x00 */

//#define CMD_STREAMING  0x18
/* out: <onoff>
 *  in: 0x00 */


#endif
/* DVB USB compliant linux driver for the Pinnacle PCTV 200e DVB-T USB2.0 receiver.
 *
 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@xxxxxxx)
 *
 *	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, version 2.
 *
 * see Documentation/dvb/README.dvb-usb for more information
 */
#include "pctv.h"

#include "mt352.h"

/* debug */
int dvb_usb_pctv_debug;
module_param_named(debug,dvb_usb_pctv_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=debug (or-able))." DVB_USB_DEBUG_STATUS);

static int pctv_msg(struct dvb_usb_device *d, u8 cmd,
		u8 *wbuf, int wlen, u8 *rbuf, int rlen)
{
	int ret;
	u8 sndbuf[wlen+1],
	   rcvbuf[rlen+2];
	memset(sndbuf,0,wlen+1);

	sndbuf[0] = cmd;
	memcpy(&sndbuf[1],wbuf,wlen);

	if ((ret = dvb_usb_generic_rw(d,sndbuf,wlen+1,rcvbuf,rlen+2,0)) < 0)
		return ret;

	if (rcvbuf[0] != sndbuf[0] ||
		rcvbuf[1] != 0x00)
		err("probably a xfer error");

	memcpy(rbuf,&rcvbuf[2],rlen);

	if (rlen > 0)
		deb_info("rbuf[0]: %x, rlen: %d\n",rbuf[0],rlen);

	return 0;
}

static int pctv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
	static u8 obuf[255];
	int i,read;;

	if (down_interruptible(&d->i2c_sem) < 0)
		return -EAGAIN;

	if (num > 2)
		warn("more than 2 i2c messages at a time is not handled yet. TODO.");

	for (i = 0; i < num; i++) {
		read = i+1 < num && (msg[i+1].flags & I2C_M_RD);

		obuf[0] = msg[i].addr << 1;
		obuf[1] = msg[i].len;

		/* read request */
		if (read)
			obuf[2] = msg[i+1].len;

		memcpy(&obuf[2+read],msg[i].buf,msg[i].len);

		if (read)
			pctv_msg(d,CMD_I2C_READ,obuf,msg[i].len+3,msg[i+1].buf,msg[i+1].len);
		else
			pctv_msg(d,CMD_I2C_WRITE,obuf,msg[i].len+2,NULL,0);

		i += read;

	}

	up(&d->i2c_sem);
	return i;
}

static u32 pctv_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C;
}

static struct i2c_algorithm pctv_i2c_algo = {
	.name          = "Pinnacle PCTV USB I2C algorithm",
	.id            = I2C_ALGO_BIT,
	.master_xfer   = pctv_i2c_xfer,
	.functionality = pctv_i2c_func,
};

/* GPIO */
static void pctv_gpio_tuner(struct dvb_usb_device *d, int onoff)
{
//struct cxusb_state *st = d->priv;
	u8 o;

//	if (st->gpio_write_state[GPIO_TUNER] == onoff)
//		return;

	o = onoff;
	pctv_msg(d,CMD_GPIO_TUNER,&o,1,NULL,0);
}

static int pctv_power_ctrl(struct dvb_usb_device *d, int onoff)
{
	return 0;
}

static int pctv_streaming_ctrl(struct dvb_usb_device *d, int onoff)
{
	return 0;
}

static int pctv_mt352_demod_init(struct dvb_frontend *fe)
{
	static u8 reset_buf[] = { 0x89, 0xbd,  0x8a, 0x28, 0x50, 0x80 };
	static u8 init_buf[] = { 0x50, 0x00, 0x8e, 0x40,  0x56, 0x31, 0x57, 0xb5,
		0x8b, 0x09, 0x88, 0x0d, 0x7b, 0x04, 0x53, 0xf4, 0x5e, 0x01, 0x54,
		0x73, 0x55, 0x1c, 0x75, 0x30, 0x67, 0x1c, 0x67, 0x00 };
	int i;

	for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
		mt352_write(fe, &reset_buf[i], 2);

	msleep(1);

	for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
		mt352_write(fe, &init_buf[i], 2);

	return 0;
}

static struct mt352_config pctv_mt352_config = {
	.demod_address = 0x1f,

	.demod_init = pctv_mt352_demod_init,

//.pll_init = NULL, /* it'll be mt2060_init */
	.pll_set = dvb_usb_pll_set, /* probably not, it's rather mt2060_set */
};

/* Callbacks for DVB USB */
static int pctv_tuner_attach(struct dvb_usb_device *d)
{
	u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 };
	d->pll_addr = 0x61;
	memcpy(d->pll_init,bpll,4);
	d->pll_desc = &dvb_pll_fmd1216me;
	return 0;
}

static int pctv_frontend_attach(struct dvb_usb_device *d)
{
	u8 o=0,i=0;

	pctv_msg(d,0x10,&o,1,&i,1);

	pctv_msg(d,0x15,NULL,0,NULL,0);

	pctv_gpio_tuner(d, 0);
	if ((d->fe = mt352_attach(&pctv_mt352_config, &d->i2c_adap)) != NULL)
		return 0;

	return -EIO;
}

/* DVB USB Driver stuff */
static struct dvb_usb_properties pctv_properties;

static int pctv_probe(struct usb_interface *intf,
		const struct usb_device_id *id)
{
	return dvb_usb_device_init(intf,&pctv_properties,THIS_MODULE,NULL);
}

static struct usb_device_id pctv_table [] = {
		{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_200E) },
		{}		/* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, pctv_table);

static struct dvb_usb_properties pctv_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,

	.size_of_priv     = 0,

	.streaming_ctrl   = pctv_streaming_ctrl,
	.power_ctrl       = pctv_power_ctrl,
	.frontend_attach  = pctv_frontend_attach,
	.tuner_attach     = pctv_tuner_attach,

	.i2c_algo         = &pctv_i2c_algo,

	.generic_bulk_ctrl_endpoint = 0x01,
	/* parameter for the MPEG2-data transfer */
	.urb = {
		.type = DVB_USB_BULK,
		.count = 7,
		.endpoint = 0x02,
		.u = {
			.bulk = {
				.buffersize = 4096,
			}
		}
	},

	.num_device_descs = 1,
	.devices = {
		{   "Pinnacle 200e DVB-T USB2.0",
			{ NULL },
			{ &pctv_table[0], NULL },
		},
	}
};

static struct usb_driver pctv_driver = {
	.owner		= THIS_MODULE,
	.name		= "pctv_200e",
	.probe		= pctv_probe,
	.disconnect = dvb_usb_device_exit,
	.id_table	= pctv_table,
};

/* module stuff */
static int __init pctv_module_init(void)
{
	int result;
	if ((result = usb_register(&pctv_driver))) {
		err("usb_register failed. Error number %d",result);
		return result;
	}

	return 0;
}

static void __exit pctv_module_exit(void)
{
	/* deregister this driver from the USB subsystem */
	usb_deregister(&pctv_driver);
}

module_init (pctv_module_init);
module_exit (pctv_module_exit);

MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@xxxxxxx>");
MODULE_DESCRIPTION("Driver for Pinnacle 200e DVB-T USB2.0 receiver");
MODULE_VERSION("1.0-alpha");
MODULE_LICENSE("GPL");

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux