int solo_p2m_init(struct solo6010_dev *solo_dev) { struct solo_p2m_dev *p2m_dev; int i; for (i = 0; i < SOLO_NR_P2M; i++) { p2m_dev = &solo_dev->p2m_dev[i]; sema_init(&p2m_dev->sem, 1); init_completion(&p2m_dev->completion); solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(i), __pa(p2m_dev->desc)); solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0); solo_reg_write(solo_dev, SOLO_P2M_CONFIG(i), SOLO_P2M_CSC_16BIT_565 | SOLO_P2M_DMA_INTERVAL(0) | SOLO_P2M_PCI_MASTER_MODE); solo6010_irq_on(solo_dev, SOLO_IRQ_P2M(i)); } run_p2m_test(solo_dev); return 0; }
static int solo_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct solo6010_dev *solo_dev = adap->algo_data; unsigned long timeout; int ret; int i; DEFINE_WAIT(wait); for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { if (&solo_dev->i2c_adap[i] == adap) break; } if (i == SOLO_I2C_ADAPTERS) return num; down(&solo_dev->i2c_sem); solo_dev->i2c_id = i; solo_dev->i2c_msg = msgs; solo_dev->i2c_msg_num = num; solo_dev->i2c_msg_ptr = 0; solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0); solo6010_irq_on(solo_dev, SOLO_IRQ_IIC); solo_i2c_start(solo_dev); timeout = HZ / 2; for (;;) { prepare_to_wait(&solo_dev->i2c_wait, &wait, TASK_INTERRUPTIBLE); if (solo_dev->i2c_state == IIC_STATE_STOP) break; timeout = schedule_timeout(timeout); if (!timeout) break; if (signal_pending(current)) break; } finish_wait(&solo_dev->i2c_wait, &wait); ret = num - solo_dev->i2c_msg_num; solo_dev->i2c_state = IIC_STATE_IDLE; solo_dev->i2c_id = -1; up(&solo_dev->i2c_sem); return ret; }
int solo_v4l2_init(struct solo6010_dev *solo_dev) { int ret; int i; init_waitqueue_head(&solo_dev->disp_thread_wait); solo_dev->vfd = video_device_alloc(); if (!solo_dev->vfd) return -ENOMEM; *solo_dev->vfd = solo_v4l2_template; solo_dev->vfd->parent = &solo_dev->pdev->dev; ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, video_nr); if (ret < 0) { video_device_release(solo_dev->vfd); solo_dev->vfd = NULL; return ret; } video_set_drvdata(solo_dev->vfd, solo_dev); snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", SOLO6010_NAME, solo_dev->vfd->num); if (video_nr != -1) video_nr++; dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with " "%d inputs (%d extended)\n", solo_dev->vfd->num, solo_dev->nr_chans, solo_dev->nr_ext); /* Cycle all the channels and clear */ for (i = 0; i < solo_dev->nr_chans; i++) { solo_v4l2_set_ch(solo_dev, i); while (erase_off(solo_dev)) ;// Do nothing } /* Set the default display channel */ solo_v4l2_set_ch(solo_dev, 0); while (erase_off(solo_dev)) ;// Do nothing solo6010_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); return 0; }
static int __devinit solo6010_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct solo6010_dev *solo_dev; int ret; u8 chip_id; solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL); if (solo_dev == NULL) return -ENOMEM; if (id->driver_data == SOLO_DEV_6010) dev_info(&pdev->dev, "Probing Softlogic 6010\n"); else dev_info(&pdev->dev, "Probing Softlogic 6110\n"); solo_dev->type = id->driver_data; solo_dev->pdev = pdev; spin_lock_init(&solo_dev->reg_io_lock); pci_set_drvdata(pdev, solo_dev); solo_dev->p2m_jiffies = msecs_to_jiffies(100); /* Only for during init */ if ((ret = pci_enable_device(pdev))) goto fail_probe; pci_set_master(pdev); /* RETRY/TRDY Timeout disabled */ pci_write_config_byte(pdev, 0x40, 0x00); pci_write_config_byte(pdev, 0x41, 0x00); if ((ret = pci_request_regions(pdev, SOLO6010_NAME))) goto fail_probe; if ((solo_dev->reg_base = pci_ioremap_bar(pdev, 0)) == NULL) { ret = -ENOMEM; goto fail_probe; } chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) & SOLO_CHIP_ID_MASK; switch (chip_id) { case 7: solo_dev->nr_chans = 16; solo_dev->nr_ext = 5; break; case 6: solo_dev->nr_chans = 8; solo_dev->nr_ext = 2; break; default: dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, " "defaulting to 4 channels\n", chip_id); case 5: solo_dev->nr_chans = 4; solo_dev->nr_ext = 1; } /* Disable all interrupts to start */ solo6010_irq_off(solo_dev, ~0); /* Initial global settings */ if (solo_dev->type == SOLO_DEV_6010) { solo_dev->clock_mhz = 108; solo_reg_write(solo_dev, SOLO_SYS_CFG, SOLO_SYS_CFG_SDRAM64BIT | SOLO_SYS_CFG_INPUTDIV(25) | SOLO_SYS_CFG_FEEDBACKDIV((solo_dev->clock_mhz * 2) - 2) | SOLO_SYS_CFG_OUTDIV(3)); } else { u32 divq, divf; solo_dev->clock_mhz = 135; if (solo_dev->clock_mhz < 125) { divq = 3; divf = (solo_dev->clock_mhz * 4) / 3 - 1; } else { divq = 2; divf = (solo_dev->clock_mhz * 2) / 3 - 1; } solo_reg_write(solo_dev, SOLO_PLL_CONFIG, (1 << 20) | /* PLL_RANGE */ (8 << 15) | /* PLL_DIVR */ (divq << 12 ) | (divf << 4 ) | (1 << 1) /* PLL_FSEN */ ); solo_reg_write(solo_dev, SOLO_SYS_CFG, SOLO_SYS_CFG_SDRAM64BIT); } solo_reg_write(solo_dev, SOLO_TIMER_CLOCK_NUM, solo_dev->clock_mhz - 1); /* PLL locking time of 1ms */ mdelay(1); ret = request_irq(pdev->irq, solo6010_isr, IRQF_SHARED, SOLO6010_NAME, solo_dev); if (ret) goto fail_probe; /* Handle this from the start */ solo6010_irq_on(solo_dev, SOLO_IRQ_PCI_ERR); if ((ret = solo_i2c_init(solo_dev))) goto fail_probe; /* Setup the DMA engine */ solo_reg_write(solo_dev, SOLO_DMA_CTRL, SOLO_DMA_CTRL_REFRESH_CYCLE(1) | SOLO_DMA_CTRL_SDRAM_SIZE(2) | SOLO_DMA_CTRL_SDRAM_CLK_INVERT | SOLO_DMA_CTRL_READ_CLK_SELECT | SOLO_DMA_CTRL_LATENCY(1)); /* Undocumented crap */ if (solo_dev->type == SOLO_DEV_6010) { solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 1 << 8); } else { solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 3 << 8); solo_dev->usec_lsb = 0x3f; solo_set_time(solo_dev); } /* Disable watchdog */ solo_reg_write(solo_dev, SOLO_TIMER_WATCHDOG, 0xff); /* Initialize sub components */ if ((ret = solo_p2m_init(solo_dev))) goto fail_probe; if ((ret = solo_disp_init(solo_dev))) goto fail_probe; if ((ret = solo_gpio_init(solo_dev))) goto fail_probe; if ((ret = solo_tw28_init(solo_dev))) goto fail_probe; if ((ret = solo_v4l2_init(solo_dev))) goto fail_probe; if ((ret = solo_enc_init(solo_dev))) goto fail_probe; if ((ret = solo_enc_v4l2_init(solo_dev))) goto fail_probe; if ((ret = solo_g723_init(solo_dev))) goto fail_probe; if ((ret = solo_sysfs_init(solo_dev))) goto fail_probe; /* Now that init is over, set this lower */ solo_dev->p2m_jiffies = msecs_to_jiffies(50); return 0; fail_probe: free_solo_dev(solo_dev); return ret; }
static int __devinit solo6010_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct solo6010_dev *solo_dev; int ret; int sdram; u8 chip_id; if ((solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL)) == NULL) return -ENOMEM; solo_dev->pdev = pdev; spin_lock_init(&solo_dev->reg_io_lock); pci_set_drvdata(pdev, solo_dev); if ((ret = pci_enable_device(pdev))) goto fail_probe; pci_set_master(pdev); if ((ret = pci_request_regions(pdev, SOLO6010_NAME))) goto fail_probe; if ((solo_dev->reg_base = pci_ioremap_bar(pdev, 0)) == NULL) { ret = -ENOMEM; goto fail_probe; } chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) & SOLO_CHIP_ID_MASK; switch (chip_id) { case 7: solo_dev->nr_chans = 16; solo_dev->nr_ext = 5; break; case 6: solo_dev->nr_chans = 8; solo_dev->nr_ext = 2; break; default: dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, " "defaulting to 4 channels\n", chip_id); case 5: solo_dev->nr_chans = 4; solo_dev->nr_ext = 1; } /* Disable all interrupts to start */ solo6010_irq_off(solo_dev, ~0); /* Initial global settings */ solo_reg_write(solo_dev, SOLO_SYS_CFG, SOLO_SYS_CFG_SDRAM64BIT | SOLO_SYS_CFG_INPUTDIV(25) | SOLO_SYS_CFG_FEEDBACKDIV((SOLO_CLOCK_MHZ * 2) - 2) | SOLO_SYS_CFG_OUTDIV(3)); solo_reg_write(solo_dev, SOLO_TIMER_CLOCK_NUM, SOLO_CLOCK_MHZ - 1); /* PLL locking time of 1ms */ mdelay(1); ret = request_irq(pdev->irq, solo6010_isr, IRQF_SHARED, SOLO6010_NAME, solo_dev); if (ret) goto fail_probe; /* Handle this from the start */ solo6010_irq_on(solo_dev, SOLO_IRQ_PCI_ERR); if ((ret = solo_i2c_init(solo_dev))) goto fail_probe; /* Setup the DMA engine */ sdram = (solo_dev->nr_chans >= 8) ? 2 : 1; solo_reg_write(solo_dev, SOLO_DMA_CTRL, SOLO_DMA_CTRL_REFRESH_CYCLE(1) | SOLO_DMA_CTRL_SDRAM_SIZE(sdram) | SOLO_DMA_CTRL_SDRAM_CLK_INVERT | SOLO_DMA_CTRL_READ_CLK_SELECT | SOLO_DMA_CTRL_LATENCY(1)); if ((ret = solo_p2m_init(solo_dev))) goto fail_probe; if ((ret = solo_disp_init(solo_dev))) goto fail_probe; if ((ret = solo_gpio_init(solo_dev))) goto fail_probe; if ((ret = solo_tw28_init(solo_dev))) goto fail_probe; if ((ret = solo_v4l2_init(solo_dev))) goto fail_probe; if ((ret = solo_enc_init(solo_dev))) goto fail_probe; if ((ret = solo_enc_v4l2_init(solo_dev))) goto fail_probe; if ((ret = solo_g723_init(solo_dev))) goto fail_probe; return 0; fail_probe: free_solo_dev(solo_dev); return ret; }