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; }
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); }
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; }
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; }
/* 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; }
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; }
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; }
/* 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; }
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; }