Example #1
0
static int au0828_dvb_start_feed(struct dvb_demux_feed *feed)
{
	struct dvb_demux *demux = feed->demux;
	struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
	struct au0828_dvb *dvb = &dev->dvb;
	int ret = 0;

	dprintk(1, "%s()\n", __func__);

	if (!demux->dmx.frontend)
		return -EINVAL;

	if (dvb) {
		mutex_lock(&dvb->lock);
		if (dvb->feeding++ == 0) {
			/* Start transport */
			au0828_write(dev, 0x608, 0x90);
			au0828_write(dev, 0x609, 0x72);
			au0828_write(dev, 0x60a, 0x71);
			au0828_write(dev, 0x60b, 0x01);
			ret = start_urb_transfer(dev);
		}
		mutex_unlock(&dvb->lock);
	}

	return ret;
}
Example #2
0
static void au0828_restart_dvb_streaming(struct work_struct *work)
{
	struct au0828_dev *dev = container_of(work, struct au0828_dev,
					      restart_streaming);
	struct au0828_dvb *dvb = &dev->dvb;
	int ret;

	if (dev->urb_streaming == 0)
		return;

	dprintk(1, "Restarting streaming...!\n");

	mutex_lock(&dvb->lock);

	/* Stop transport */
	ret = stop_urb_transfer(dev);
	au0828_write(dev, 0x608, 0x00);
	au0828_write(dev, 0x609, 0x00);
	au0828_write(dev, 0x60a, 0x00);
	au0828_write(dev, 0x60b, 0x00);

	/* Start transport */
	au0828_write(dev, 0x608, 0x90);
	au0828_write(dev, 0x609, 0x72);
	au0828_write(dev, 0x60a, 0x71);
	au0828_write(dev, 0x60b, 0x01);
	ret = start_urb_transfer(dev);

	mutex_unlock(&dvb->lock);
}
Example #3
0
static int au0828_usb_probe(struct usb_interface *interface,
    const struct usb_device_id *id)
{
    int ifnum;
    struct au0828_dev *dev;
    struct usb_device *usbdev = interface_to_usbdev(interface);

    ifnum = interface->altsetting->desc.bInterfaceNumber;

    if (ifnum != 0)
        return -ENODEV;

    dprintk(1, "%s() vendor id 0x%x device id 0x%x ifnum:%d\n", __func__,
        le16_to_cpu(usbdev->descriptor.idVendor),
        le16_to_cpu(usbdev->descriptor.idProduct),
        ifnum);

    dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    if (dev == NULL) {
        printk(KERN_ERR "%s() Unable to allocate memory\n", __func__);
        return -ENOMEM;
    }

    mutex_init(&dev->mutex);
    mutex_init(&dev->dvb.lock);
    dev->usbdev = usbdev;
    dev->board = id->driver_info;

    usb_set_intfdata(interface, dev);

    /* Power Up the bridge */
    au0828_write(dev, REG_600, 1 << 4);

    /* Bring up the GPIO's and supporting devices */
    au0828_gpio_setup(dev);

    /* I2C */
    au0828_i2c_register(dev);

    /* Setup */
    au0828_card_setup(dev);

    /* Digital TV */
    au0828_dvb_register(dev);

    printk(KERN_INFO "Registered device AU0828 [%s]\n",
        au0828_boards[dev->board].name == NULL ? "Unset" :
        au0828_boards[dev->board].name);

    return 0;
}
Example #4
0
static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
{
	struct dvb_demux *demux = feed->demux;
	struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
	struct au0828_dvb *dvb = &dev->dvb;
	int ret = 0;

	dprintk(1, "%s()\n", __func__);

	if (dvb) {
		mutex_lock(&dvb->lock);
		if (--dvb->feeding == 0) {
			/* Stop transport */
			au0828_write(dev, 0x608, 0x00);
			au0828_write(dev, 0x609, 0x00);
			au0828_write(dev, 0x60a, 0x00);
			au0828_write(dev, 0x60b, 0x00);
			ret = stop_urb_transfer(dev);
		}
		mutex_unlock(&dvb->lock);
	}

	return ret;
}
Example #5
0
/* FIXME: Implement join handling correctly */
static int i2c_readbytes(struct i2c_adapter *i2c_adap,
	const struct i2c_msg *msg, int joined)
{
	struct au0828_dev *dev = i2c_adap->algo_data;
	int i;

	dprintk(4, "%s()\n", __func__);

	au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);

	/* Set the I2C clock */
	au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
		     dev->board.i2c_clk_divider);

	/* Hardware needs 8 bit addresses */
	au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);

	dprintk(4, " RECV:\n");

	/* Deal with i2c_scan */
	if (msg->len == 0) {
		au0828_write(dev, AU0828_I2C_TRIGGER_200,
			     AU0828_I2C_TRIGGER_READ);

		if (i2c_wait_read_ack(i2c_adap))
			return -EIO;
		return 0;
	}

	for (i = 0; i < msg->len;) {

		i++;

		if (i < msg->len)
			au0828_write(dev, AU0828_I2C_TRIGGER_200,
				     AU0828_I2C_TRIGGER_READ |
				     AU0828_I2C_TRIGGER_HOLD);
		else
			au0828_write(dev, AU0828_I2C_TRIGGER_200,
				     AU0828_I2C_TRIGGER_READ);

		if (!i2c_wait_read_done(i2c_adap))
			return -EIO;

		msg->buf[i-1] = au0828_read(dev, AU0828_I2C_READ_FIFO_209) &
			0xff;

		dprintk(4, " %02x\n", msg->buf[i-1]);
	}
	if (!i2c_wait_done(i2c_adap))
		return -EIO;

	dprintk(4, "\n");

	return msg->len;
}
/* FIXME: Implement join handling correctly */
static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
	const struct i2c_msg *msg, int joined_rlen)
{
	int i, strobe = 0;
	struct au0828_dev *dev = i2c_adap->algo_data;

	dprintk(4, "%s()\n", __func__);

	au0828_write(dev, REG_2FF, 0x01);
	au0828_write(dev, REG_202, 0x07);

	/* Hardware needs 8 bit addresses */
	au0828_write(dev, REG_203, msg->addr << 1);

	dprintk(4, "SEND: %02x\n", msg->addr);

	for (i = 0; i < msg->len;) {

		dprintk(4, " %02x\n", msg->buf[i]);

		au0828_write(dev, REG_205, msg->buf[i]);

		strobe++;
		i++;

		if ((strobe >= 4) || (i >= msg->len)) {

			/* Strobe the byte into the bus */
			if (i < msg->len)
				au0828_write(dev, REG_200, 0x41);
			else
				au0828_write(dev, REG_200, 0x01);

			/* Reset strobe trigger */
			strobe = 0;

			if (!i2c_wait_write_done(i2c_adap))
				return -EIO;

		}

	}
	if (!i2c_wait_done(i2c_adap))
		return -EIO;

	dprintk(4, "\n");

	return msg->len;
}
/* FIXME: Implement join handling correctly */
static int i2c_readbytes(struct i2c_adapter *i2c_adap,
	const struct i2c_msg *msg, int joined)
{
	struct au0828_dev *dev = i2c_adap->algo_data;
	int i;

	dprintk(4, "%s()\n", __func__);

	au0828_write(dev, REG_2FF, 0x01);
	au0828_write(dev, REG_202, 0x07);

	/* Hardware needs 8 bit addresses */
	au0828_write(dev, REG_203, msg->addr << 1);

	dprintk(4, " RECV:\n");

	/* Deal with i2c_scan */
	if (msg->len == 0) {
		au0828_write(dev, REG_200, 0x20);
		if (i2c_wait_read_ack(i2c_adap))
			return -EIO;
		return 0;
	}

	for (i = 0; i < msg->len;) {

		i++;

		if (i < msg->len)
			au0828_write(dev, REG_200, 0x60);
		else
			au0828_write(dev, REG_200, 0x20);

		if (!i2c_wait_read_done(i2c_adap))
			return -EIO;

		msg->buf[i-1] = au0828_read(dev, REG_209) & 0xff;

		dprintk(4, " %02x\n", msg->buf[i-1]);
	}
	if (!i2c_wait_done(i2c_adap))
		return -EIO;

	dprintk(4, "\n");

	return msg->len;
}
Example #8
0
static int au0828_resume(struct usb_interface *interface)
{
	struct au0828_dev *dev = usb_get_intfdata(interface);
	if (!dev)
		return 0;

	pr_info("Resume\n");

	/* Power Up the bridge */
	au0828_write(dev, REG_600, 1 << 4);

	/* Bring up the GPIO's and supporting devices */
	au0828_gpio_setup(dev);

	au0828_rc_resume(dev);
	au0828_v4l2_resume(dev);
	au0828_dvb_resume(dev);

	/* FIXME: should resume also ATV/DTV */

	return 0;
}
Example #9
0
static int au0828_usb_probe(struct usb_interface *interface,
	const struct usb_device_id *id)
{
	int ifnum;
	int retval = 0;

	struct au0828_dev *dev;
	struct usb_device *usbdev = interface_to_usbdev(interface);

	ifnum = interface->altsetting->desc.bInterfaceNumber;

	if (ifnum != 0)
		return -ENODEV;

	dprintk(1, "%s() vendor id 0x%x device id 0x%x ifnum:%d\n", __func__,
		le16_to_cpu(usbdev->descriptor.idVendor),
		le16_to_cpu(usbdev->descriptor.idProduct),
		ifnum);

	/*
	 * Make sure we have 480 Mbps of bandwidth, otherwise things like
	 * video stream wouldn't likely work, since 12 Mbps is generally
	 * not enough even for most Digital TV streams.
	 */
	if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
		pr_err("au0828: Device initialization failed.\n");
		pr_err("au0828: Device must be connected to a high-speed USB 2.0 port.\n");
		return -ENODEV;
	}

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (dev == NULL) {
		pr_err("%s() Unable to allocate memory\n", __func__);
		return -ENOMEM;
	}

	mutex_init(&dev->lock);
	mutex_lock(&dev->lock);
	mutex_init(&dev->mutex);
	mutex_init(&dev->dvb.lock);
	dev->usbdev = usbdev;
	dev->boardnr = id->driver_info;

#ifdef CPTCFG_VIDEO_AU0828_V4L2
	dev->v4l2_dev.release = au0828_usb_v4l2_release;

	/* Create the v4l2_device */
	retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
	if (retval) {
		pr_err("%s() v4l2_device_register failed\n",
		       __func__);
		mutex_unlock(&dev->lock);
		kfree(dev);
		return retval;
	}
	/* This control handler will inherit the controls from au8522 */
	retval = v4l2_ctrl_handler_init(&dev->v4l2_ctrl_hdl, 4);
	if (retval) {
		pr_err("%s() v4l2_ctrl_handler_init failed\n",
		       __func__);
		mutex_unlock(&dev->lock);
		kfree(dev);
		return retval;
	}
	dev->v4l2_dev.ctrl_handler = &dev->v4l2_ctrl_hdl;
#endif

	/* Power Up the bridge */
	au0828_write(dev, REG_600, 1 << 4);

	/* Bring up the GPIO's and supporting devices */
	au0828_gpio_setup(dev);

	/* I2C */
	au0828_i2c_register(dev);

	/* Setup */
	au0828_card_setup(dev);

#ifdef CPTCFG_VIDEO_AU0828_V4L2
	/* Analog TV */
	if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED)
		au0828_analog_register(dev, interface);
#endif

	/* Digital TV */
	retval = au0828_dvb_register(dev);
	if (retval)
		pr_err("%s() au0282_dev_register failed\n",
		       __func__);

	/* Remote controller */
	au0828_rc_register(dev);

	/*
	 * Store the pointer to the au0828_dev so it can be accessed in
	 * au0828_usb_disconnect
	 */
	usb_set_intfdata(interface, dev);

	pr_info("Registered device AU0828 [%s]\n",
		dev->board.name == NULL ? "Unset" : dev->board.name);

	mutex_unlock(&dev->lock);

	return retval;
}
Example #10
0
/* FIXME: Implement join handling correctly */
static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
	const struct i2c_msg *msg, int joined_rlen)
{
	int i, strobe = 0;
	struct au0828_dev *dev = i2c_adap->algo_data;

	dprintk(4, "%s()\n", __func__);

	au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);

	/* Set the I2C clock */
	au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
		     dev->board.i2c_clk_divider);

	/* Hardware needs 8 bit addresses */
	au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);

	dprintk(4, "SEND: %02x\n", msg->addr);

	/* Deal with i2c_scan */
	if (msg->len == 0) {
		/* The analog tuner detection code makes use of the SMBUS_QUICK
		   message (which involves a zero length i2c write).  To avoid
		   checking the status register when we didn't strobe out any
		   actual bytes to the bus, just do a read check.  This is
		   consistent with how I saw i2c device checking done in the
		   USB trace of the Windows driver */
		au0828_write(dev, AU0828_I2C_TRIGGER_200,
			     AU0828_I2C_TRIGGER_READ);

		if (!i2c_wait_done(i2c_adap))
			return -EIO;

		if (i2c_wait_read_ack(i2c_adap))
			return -EIO;

		return 0;
	}

	for (i = 0; i < msg->len;) {

		dprintk(4, " %02x\n", msg->buf[i]);

		au0828_write(dev, AU0828_I2C_WRITE_FIFO_205, msg->buf[i]);

		strobe++;
		i++;

		if ((strobe >= 4) || (i >= msg->len)) {

			/* Strobe the byte into the bus */
			if (i < msg->len)
				au0828_write(dev, AU0828_I2C_TRIGGER_200,
					     AU0828_I2C_TRIGGER_WRITE |
					     AU0828_I2C_TRIGGER_HOLD);
			else
				au0828_write(dev, AU0828_I2C_TRIGGER_200,
					     AU0828_I2C_TRIGGER_WRITE);

			/* Reset strobe trigger */
			strobe = 0;

			if (!i2c_wait_write_done(i2c_adap))
				return -EIO;

		}

	}
	if (!i2c_wait_done(i2c_adap))
		return -EIO;

	dprintk(4, "\n");

	return msg->len;
}
Example #11
0
static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
	const struct i2c_msg *msg, int joined_rlen)
{
	int i, strobe = 0;
	struct au0828_dev *dev = i2c_adap->algo_data;

	dprintk(4, "%s()\n", __func__);

	au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);

	
	au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
		     dev->board.i2c_clk_divider);

	
	au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);

	dprintk(4, "SEND: %02x\n", msg->addr);

	
	if (msg->len == 0) {
		
		au0828_write(dev, AU0828_I2C_TRIGGER_200,
			     AU0828_I2C_TRIGGER_READ);

		if (!i2c_wait_done(i2c_adap))
			return -EIO;

		if (i2c_wait_read_ack(i2c_adap))
			return -EIO;

		return 0;
	}

	for (i = 0; i < msg->len;) {

		dprintk(4, " %02x\n", msg->buf[i]);

		au0828_write(dev, AU0828_I2C_WRITE_FIFO_205, msg->buf[i]);

		strobe++;
		i++;

		if ((strobe >= 4) || (i >= msg->len)) {

			
			if (i < msg->len)
				au0828_write(dev, AU0828_I2C_TRIGGER_200,
					     AU0828_I2C_TRIGGER_WRITE |
					     AU0828_I2C_TRIGGER_HOLD);
			else
				au0828_write(dev, AU0828_I2C_TRIGGER_200,
					     AU0828_I2C_TRIGGER_WRITE);

			
			strobe = 0;

			if (!i2c_wait_write_done(i2c_adap))
				return -EIO;

		}

	}
	if (!i2c_wait_done(i2c_adap))
		return -EIO;

	dprintk(4, "\n");

	return msg->len;
}