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; }