コード例 #1
0
ファイル: spi-altera.c プロジェクト: GerardGarcia/linux
static int __devinit altera_spi_probe(struct platform_device *pdev)
{
	struct altera_spi_platform_data *platp = pdev->dev.platform_data;
	struct altera_spi *hw;
	struct spi_master *master;
	struct resource *res;
	int err = -ENODEV;

	master = spi_alloc_master(&pdev->dev, sizeof(struct altera_spi));
	if (!master)
		return err;

	/* setup the master state. */
	master->bus_num = pdev->id;
	master->num_chipselect = 16;
	master->mode_bits = SPI_CS_HIGH;
	master->setup = altera_spi_setup;

	hw = spi_master_get_devdata(master);
	platform_set_drvdata(pdev, hw);

	/* setup the state for the bitbang driver */
	hw->bitbang.master = spi_master_get(master);
	if (!hw->bitbang.master)
		return err;
	hw->bitbang.setup_transfer = altera_spi_setupxfer;
	hw->bitbang.chipselect = altera_spi_chipsel;
	hw->bitbang.txrx_bufs = altera_spi_txrx;

	/* find and map our resources */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		goto exit_busy;
	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
				     pdev->name))
		goto exit_busy;
	hw->base = devm_ioremap_nocache(&pdev->dev, res->start,
					resource_size(res));
	if (!hw->base)
		goto exit_busy;
	/* program defaults into the registers */
	hw->imr = 0;		/* disable spi interrupts */
	writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
	writel(0, hw->base + ALTERA_SPI_STATUS);	/* clear status reg */
	if (readl(hw->base + ALTERA_SPI_STATUS) & ALTERA_SPI_STATUS_RRDY_MSK)
		readl(hw->base + ALTERA_SPI_RXDATA);	/* flush rxdata */
	/* irq is optional */
	hw->irq = platform_get_irq(pdev, 0);
	if (hw->irq >= 0) {
		init_completion(&hw->done);
		err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0,
				       pdev->name, hw);
		if (err)
			goto exit;
	}
	/* find platform data */
	if (!platp)
		hw->bitbang.master->dev.of_node = pdev->dev.of_node;

	/* register our spi controller */
	err = spi_bitbang_start(&hw->bitbang);
	if (err)
		goto exit;
	dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq);

	return 0;

exit_busy:
	err = -EBUSY;
exit:
	platform_set_drvdata(pdev, NULL);
	spi_master_put(master);
	return err;
}
コード例 #2
0
ファイル: spi_stm.c プロジェクト: geraldmusch/satip-axe
static int __init spi_stm_probe(struct platform_device *pdev)
{
	struct stm_plat_ssc_data *plat_data = pdev->dev.platform_data;
	struct spi_master *master;
	struct resource *res;
	struct spi_stm *spi_stm;
	u32 reg;
	int status = 0;

	master = spi_alloc_master(&pdev->dev, sizeof(struct spi_stm));
	if (!master) {
		dev_err(&pdev->dev, "failed to allocate spi master\n");
		status = -ENOMEM;
		goto err0;
	}

	platform_set_drvdata(pdev, master);

	spi_stm = spi_master_get_devdata(master);
	spi_stm->bitbang.master = spi_master_get(master);
	spi_stm->bitbang.setup_transfer = spi_stm_setup_transfer;
	spi_stm->bitbang.txrx_bufs = spi_stm_txrx_bufs;
	spi_stm->bitbang.master->setup = spi_stm_setup;
	spi_stm->bitbang.master->cleanup = spi_stm_cleanup;

	if (plat_data->spi_chipselect)
		spi_stm->bitbang.chipselect = plat_data->spi_chipselect;
	else
		spi_stm->bitbang.chipselect = spi_stm_gpio_chipselect;

	/* the spi->mode bits understood by this driver: */
	master->mode_bits = MODEBITS;

	/* chip_select field of spi_device is declared as u8 and therefore
	 * limits number of GPIOs that can be used as a CS line. Sorry. */
	master->num_chipselect =
		sizeof(((struct spi_device *)0)->chip_select) * 256;
	master->bus_num = pdev->id;
	init_completion(&spi_stm->done);

	/* Get resources */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to find IOMEM resource\n");
		status = -ENOENT;
		goto err1;
	}
	spi_stm->r_mem = *res;

	if (!request_mem_region(res->start,
				res->end - res->start + 1, NAME)) {
		dev_err(&pdev->dev, "request memory region failed [0x%x]\n",
			res->start);
		status = -EBUSY;
		goto err1;
	}

	spi_stm->base = ioremap_nocache(res->start, res->end - res->start + 1);
	if (!spi_stm->base) {
		dev_err(&pdev->dev, "ioremap memory failed [0x%x]\n",
			res->start);
		status = -ENXIO;
		goto err2;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to find IRQ resource\n");
		status = -ENOENT;
		goto err3;
	}
	spi_stm->r_irq = *res;

	if (request_irq(res->start, spi_stm_irq,
			IRQF_DISABLED, dev_name(&pdev->dev), spi_stm)) {
		dev_err(&pdev->dev, "irq request failed\n");
		status = -EBUSY;
		goto err3;
	}

	spi_stm->pad_state = stm_pad_claim(plat_data->pad_config,
					   dev_name(&pdev->dev));
	if (!spi_stm->pad_state) {
		dev_err(&pdev->dev, "pads request failed\n");
		status = -EBUSY;
		goto err4;
	}

	/* Disable I2C and Reset SSC */
	ssc_store32(spi_stm, SSC_I2C, 0x0);
	reg = ssc_load16(spi_stm, SSC_CTL);
	reg |= SSC_CTL_SR;
	ssc_store32(spi_stm, SSC_CTL, reg);

	udelay(1);
	reg = ssc_load32(spi_stm, SSC_CTL);
	reg &= ~SSC_CTL_SR;
	ssc_store32(spi_stm, SSC_CTL, reg);

	/* Set SSC into slave mode before reconfiguring PIO pins */
	reg = ssc_load32(spi_stm, SSC_CTL);
	reg &= ~SSC_CTL_MS;
	ssc_store32(spi_stm, SSC_CTL, reg);

	spi_stm->clk = clk_get(&pdev->dev, "comms_clk");
	if (!spi_stm->clk) {
		dev_err(&pdev->dev, "Comms clock not found!\n");
		goto err5;
	}

	clk_enable(spi_stm->clk);
	/* Start "bitbang" worker */
	status = spi_bitbang_start(&spi_stm->bitbang);
	if (status) {
		dev_err(&pdev->dev, "bitbang start failed [%d]\n", status);
		goto err5;
	}

	dev_info(&pdev->dev, "registered SPI Bus %d\n", master->bus_num);

	return status;

 err5:
	stm_pad_release(spi_stm->pad_state);
 err4:
	free_irq(spi_stm->r_irq.start, spi_stm);
 err3:
	iounmap(spi_stm->base);
 err2:
	release_mem_region(spi_stm->r_mem.start,
			   resource_size(&spi_stm->r_mem));
 err1:
	spi_master_put(spi_stm->bitbang.master);
	platform_set_drvdata(pdev, NULL);
 err0:
	return status;
}
コード例 #3
0
ファイル: ar71xx_spi.c プロジェクト: nutbolt/carambola
static int ar71xx_spi_probe(struct platform_device *pdev)
{
	struct spi_master *master;
	struct ar71xx_spi *sp;
	struct ar71xx_spi_platform_data *pdata;
	struct resource	*r;
	int ret;

	master = spi_alloc_master(&pdev->dev, sizeof(*sp));
	if (master == NULL) {
		dev_err(&pdev->dev, "failed to allocate spi master\n");
		return -ENOMEM;
	}

	sp = spi_master_get_devdata(master);
	platform_set_drvdata(pdev, sp);

	pdata = pdev->dev.platform_data;

	master->setup = ar71xx_spi_setup;
	master->cleanup = ar71xx_spi_cleanup;

	sp->bitbang.master = spi_master_get(master);
	sp->bitbang.chipselect = ar71xx_spi_chipselect;
	sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0;
	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;

	sp->get_ioc_base = ar71xx_spi_get_ioc_base;
	if (pdata) {
		sp->bitbang.master->bus_num = pdata->bus_num;
		sp->bitbang.master->num_chipselect = pdata->num_chipselect;
		if (pdata->get_ioc_base)
			sp->get_ioc_base = pdata->get_ioc_base;
	} else {
		sp->bitbang.master->bus_num = 0;
		sp->bitbang.master->num_chipselect = 3;
	}

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (r == NULL) {
		ret = -ENOENT;
		goto err1;
	}

	sp->base = ioremap_nocache(r->start, r->end - r->start + 1);
	if (!sp->base) {
		ret = -ENXIO;
		goto err1;
	}

	ar71xx_spi_setup_regs(sp);

	ret = spi_bitbang_start(&sp->bitbang);
	if (!ret)
		return 0;

	ar71xx_spi_restore_regs(sp);
	iounmap(sp->base);
err1:
	platform_set_drvdata(pdev, NULL);
	spi_master_put(sp->bitbang.master);

	return ret;
}
コード例 #4
0
/**
 * davinci_spi_probe - probe function for SPI Master Controller
 * @pdev: platform_device structure which contains plateform specific data
 */
static int davinci_spi_probe(struct platform_device *pdev)
{
	struct spi_master *master;
	struct davinci_spi *davinci_spi;
	struct davinci_spi_platform_data *pdata;
	struct resource *r, *mem;
	resource_size_t dma_rx_chan = SPI_NO_RESOURCE;
	resource_size_t	dma_tx_chan = SPI_NO_RESOURCE;
	resource_size_t	dma_eventq = SPI_NO_RESOURCE;
	int i = 0, ret = 0;

	pdata = pdev->dev.platform_data;
	if (pdata == NULL) {
		ret = -ENODEV;
		goto err;
	}

	master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi));
	if (master == NULL) {
		ret = -ENOMEM;
		goto err;
	}

	dev_set_drvdata(&pdev->dev, master);

	davinci_spi = spi_master_get_devdata(master);
	if (davinci_spi == NULL) {
		ret = -ENOENT;
		goto free_master;
	}

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (r == NULL) {
		ret = -ENOENT;
		goto free_master;
	}

	davinci_spi->pbase = r->start;
	davinci_spi->region_size = resource_size(r);
	davinci_spi->pdata = pdata;

	mem = request_mem_region(r->start, davinci_spi->region_size,
					pdev->name);
	if (mem == NULL) {
		ret = -EBUSY;
		goto free_master;
	}

	davinci_spi->base = (struct davinci_spi_reg __iomem *)
			ioremap(r->start, davinci_spi->region_size);
	if (davinci_spi->base == NULL) {
		ret = -ENOMEM;
		goto release_region;
	}

	davinci_spi->irq = platform_get_irq(pdev, 0);
	if (davinci_spi->irq <= 0) {
		ret = -EINVAL;
		goto unmap_io;
	}

	ret = request_irq(davinci_spi->irq, davinci_spi_irq, IRQF_DISABLED,
			  dev_name(&pdev->dev), davinci_spi);
	if (ret)
		goto unmap_io;

	/* Allocate tmp_buf for tx_buf */
	davinci_spi->tmp_buf = kzalloc(SPI_BUFSIZ, GFP_KERNEL);
	if (davinci_spi->tmp_buf == NULL) {
		ret = -ENOMEM;
		goto irq_free;
	}

	davinci_spi->bitbang.master = spi_master_get(master);
	if (davinci_spi->bitbang.master == NULL) {
		ret = -ENODEV;
		goto free_tmp_buf;
	}

	davinci_spi->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(davinci_spi->clk)) {
		ret = -ENODEV;
		goto put_master;
	}
	clk_enable(davinci_spi->clk);


	master->bus_num = pdev->id;
	master->num_chipselect = pdata->num_chipselect;
	master->setup = davinci_spi_setup;
	master->cleanup = davinci_spi_cleanup;

	davinci_spi->bitbang.chipselect = davinci_spi_chipselect;
	davinci_spi->bitbang.setup_transfer = davinci_spi_setup_transfer;

	davinci_spi->version = pdata->version;
	use_dma = pdata->use_dma;

	davinci_spi->bitbang.flags = SPI_NO_CS | SPI_LSB_FIRST | SPI_LOOP;
	if (davinci_spi->version == SPI_VERSION_2)
		davinci_spi->bitbang.flags |= SPI_READY;

	if (use_dma) {
			r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
			if (r)
				dma_rx_chan = r->start;
			r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
			if (r)
				dma_tx_chan = r->start;
			r = platform_get_resource(pdev, IORESOURCE_DMA, 2);
			if (r)
				dma_eventq = r->start;
	}

	if (!use_dma ||
	    dma_rx_chan == SPI_NO_RESOURCE ||
	    dma_tx_chan == SPI_NO_RESOURCE ||
	    dma_eventq	== SPI_NO_RESOURCE) {
		davinci_spi->bitbang.txrx_bufs = davinci_spi_bufs_pio;
		use_dma = 0;
	} else {
		davinci_spi->bitbang.txrx_bufs = davinci_spi_bufs_dma;
		davinci_spi->dma_channels = kzalloc(master->num_chipselect
				* sizeof(struct davinci_spi_dma), GFP_KERNEL);
		if (davinci_spi->dma_channels == NULL) {
			ret = -ENOMEM;
			goto free_clk;
		}

		for (i = 0; i < master->num_chipselect; i++) {
			davinci_spi->dma_channels[i].dma_rx_channel = -1;
			davinci_spi->dma_channels[i].dma_rx_sync_dev =
				dma_rx_chan;
			davinci_spi->dma_channels[i].dma_tx_channel = -1;
			davinci_spi->dma_channels[i].dma_tx_sync_dev =
				dma_tx_chan;
			davinci_spi->dma_channels[i].eventq = dma_eventq;
		}
		dev_info(&pdev->dev, "DaVinci SPI driver in EDMA mode\n"
				"Using RX channel = %d , TX channel = %d and "
				"event queue = %d", dma_rx_chan, dma_tx_chan,
				dma_eventq);
	}

	davinci_spi->get_rx = davinci_spi_rx_buf_u8;
	davinci_spi->get_tx = davinci_spi_tx_buf_u8;

	init_completion(&davinci_spi->done);

	/* Reset In/OUT SPI module */
	iowrite32(0, davinci_spi->base + SPIGCR0);
	udelay(100);
	iowrite32(1, davinci_spi->base + SPIGCR0);

	/* Clock internal */
	if (davinci_spi->pdata->clk_internal)
		set_io_bits(davinci_spi->base + SPIGCR1,
				SPIGCR1_CLKMOD_MASK);
	else
		clear_io_bits(davinci_spi->base + SPIGCR1,
				SPIGCR1_CLKMOD_MASK);

	/* master mode default */
	set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_MASTER_MASK);

	if (davinci_spi->pdata->intr_level)
		iowrite32(SPI_INTLVL_1, davinci_spi->base + SPILVL);
	else
		iowrite32(SPI_INTLVL_0, davinci_spi->base + SPILVL);

	ret = spi_bitbang_start(&davinci_spi->bitbang);
	if (ret)
		goto free_clk;

	dev_info(&pdev->dev, "Controller at 0x%p \n", davinci_spi->base);

	if (!pdata->poll_mode)
		dev_info(&pdev->dev, "Operating in interrupt mode"
			" using IRQ %d\n", davinci_spi->irq);

	return ret;

free_clk:
	clk_disable(davinci_spi->clk);
	clk_put(davinci_spi->clk);
put_master:
	spi_master_put(master);
free_tmp_buf:
	kfree(davinci_spi->tmp_buf);
irq_free:
	free_irq(davinci_spi->irq, davinci_spi);
unmap_io:
	iounmap(davinci_spi->base);
release_region:
	release_mem_region(davinci_spi->pbase, davinci_spi->region_size);
free_master:
	kfree(master);
err:
	return ret;
}
コード例 #5
0
static int __init s3c24xx_spi_probe(struct platform_device *pdev)
{
	struct s3c2410_spi_info *pdata;
	struct s3c24xx_spi *hw;
	struct spi_master *master;
	struct resource *res;
	int err = 0;

	master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
	if (master == NULL) {
		dev_err(&pdev->dev, "No memory for spi_master\n");
		err = -ENOMEM;
		goto err_nomem;
	}

	hw = spi_master_get_devdata(master);
	memset(hw, 0, sizeof(struct s3c24xx_spi));

	hw->master = spi_master_get(master);
	hw->pdata = pdata = pdev->dev.platform_data;
	hw->dev = &pdev->dev;

	if (pdata == NULL) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		err = -ENOENT;
		goto err_no_pdata;
	}

	platform_set_drvdata(pdev, hw);
	init_completion(&hw->done);

	/* initialise fiq handler */

	s3c24xx_spi_initfiq(hw);

	/* setup the master state. */

	/* the spi->mode bits understood by this driver: */
	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;

	master->num_chipselect = hw->pdata->num_cs;
	master->bus_num = pdata->bus_num;

	/* setup the state for the bitbang driver */

	hw->bitbang.master         = hw->master;
	hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;
	hw->bitbang.chipselect     = s3c24xx_spi_chipsel;
	hw->bitbang.txrx_bufs      = s3c24xx_spi_txrx;

	hw->master->setup  = s3c24xx_spi_setup;
	hw->master->cleanup = s3c24xx_spi_cleanup;

	dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);

	/* find and map our resources */

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
		err = -ENOENT;
		goto err_no_iores;
	}

	hw->ioarea = request_mem_region(res->start, resource_size(res),
					pdev->name);

	if (hw->ioarea == NULL) {
		dev_err(&pdev->dev, "Cannot reserve region\n");
		err = -ENXIO;
		goto err_no_iores;
	}

	hw->regs = ioremap(res->start, resource_size(res));
	if (hw->regs == NULL) {
		dev_err(&pdev->dev, "Cannot map IO\n");
		err = -ENXIO;
		goto err_no_iomap;
	}

	hw->irq = platform_get_irq(pdev, 0);
	if (hw->irq < 0) {
		dev_err(&pdev->dev, "No IRQ specified\n");
		err = -ENOENT;
		goto err_no_irq;
	}

	//err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw);
	if (err) {
		dev_err(&pdev->dev, "Cannot claim IRQ\n");
		goto err_no_irq;
	}

	hw->clk = clk_get(&pdev->dev, "spi");
	if (IS_ERR(hw->clk)) {
		dev_err(&pdev->dev, "No clock for device\n");
		err = PTR_ERR(hw->clk);
		goto err_no_clk;
	}

	/* setup any gpio we can */

	if (!pdata->set_cs) {
		if (pdata->pin_cs < 0) {
			dev_err(&pdev->dev, "No chipselect pin\n");
			goto err_register;
		}

		err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev));
		if (err) {
			dev_err(&pdev->dev, "Failed to get gpio for cs\n");
			goto err_register;
		}

		hw->set_cs = s3c24xx_spi_gpiocs;
		gpio_direction_output(pdata->pin_cs, 1);
	} else
		hw->set_cs = pdata->set_cs;

	s3c24xx_spi_initialsetup(hw);

	/* register our spi controller */

	err = spi_bitbang_start(&hw->bitbang);
	if (err) {
		dev_err(&pdev->dev, "Failed to register SPI master\n");
		goto err_register;
	}

	return 0;

 err_register:
	if (hw->set_cs == s3c24xx_spi_gpiocs)
		gpio_free(pdata->pin_cs);

	clk_disable(hw->clk);
	clk_put(hw->clk);

 err_no_clk:
	free_irq(hw->irq, hw);

 err_no_irq:
	iounmap(hw->regs);

 err_no_iomap:
	release_resource(hw->ioarea);
	kfree(hw->ioarea);

 err_no_iores:
 err_no_pdata:
	spi_master_put(hw->master);

 err_nomem:
	return err;
}
コード例 #6
0
static void spi_lm70llp_attach(struct parport *p)
{
    struct pardevice	*pd;
    struct spi_lm70llp	*pp;
    struct spi_master	*master;
    int			status;

    if (lm70llp) {
        printk(KERN_WARNING
               "%s: spi_lm70llp instance already loaded. Aborting.\n",
               DRVNAME);
        return;
    }

    /* TODO:  this just _assumes_ a lm70 is there ... no probe;
     * the lm70 driver could verify it, reading the manf ID.
     */

    master = spi_alloc_master(p->physport->dev, sizeof *pp);
    if (!master) {
        status = -ENOMEM;
        goto out_fail;
    }
    pp = spi_master_get_devdata(master);

    master->bus_num = -1;	/* dynamic alloc of a bus number */
    master->num_chipselect = 1;

    /*
     * SPI and bitbang hookup.
     */
    pp->bitbang.master = spi_master_get(master);
    pp->bitbang.chipselect = lm70_chipselect;
    pp->bitbang.txrx_word[SPI_MODE_0] = lm70_txrx;
    pp->bitbang.flags = SPI_3WIRE;

    /*
     * Parport hookup
     */
    pp->port = p;
    pd = parport_register_device(p, DRVNAME,
                                 NULL, NULL, NULL,
                                 PARPORT_FLAG_EXCL, pp);
    if (!pd) {
        status = -ENOMEM;
        goto out_free_master;
    }
    pp->pd = pd;

    status = parport_claim(pd);
    if (status < 0)
        goto out_parport_unreg;

    /*
     * Start SPI ...
     */
    status = spi_bitbang_start(&pp->bitbang);
    if (status < 0) {
        printk(KERN_WARNING
               "%s: spi_bitbang_start failed with status %d\n",
               DRVNAME, status);
        goto out_off_and_release;
    }

    /*
     * The modalias name MUST match the device_driver name
     * for the bus glue code to match and subsequently bind them.
     * We are binding to the generic drivers/hwmon/lm70.c device
     * driver.
     */
    strcpy(pp->info.modalias, "lm70");
    pp->info.max_speed_hz = 6 * 1000 * 1000;
    pp->info.chip_select = 0;
    pp->info.mode = SPI_3WIRE | SPI_MODE_0;

    /* power up the chip, and let the LM70 control SI/SO */
    parport_write_data(pp->port, lm70_INIT);

    /* Enable access to our primary data structure via
     * the board info's (void *)controller_data.
     */
    pp->info.controller_data = pp;
    pp->spidev_lm70 = spi_new_device(pp->bitbang.master, &pp->info);
    if (pp->spidev_lm70)
        dev_dbg(&pp->spidev_lm70->dev, "spidev_lm70 at %s\n",
                dev_name(&pp->spidev_lm70->dev));
    else {
        printk(KERN_WARNING "%s: spi_new_device failed\n", DRVNAME);
        status = -ENODEV;
        goto out_bitbang_stop;
    }
    pp->spidev_lm70->bits_per_word = 8;

    lm70llp = pp;
    return;

out_bitbang_stop:
    spi_bitbang_stop(&pp->bitbang);
out_off_and_release:
    /* power down */
    parport_write_data(pp->port, 0);
    mdelay(10);
    parport_release(pp->pd);
out_parport_unreg:
    parport_unregister_device(pd);
out_free_master:
    (void) spi_master_put(master);
out_fail:
    pr_info("%s: spi_lm70llp probe fail, status %d\n", DRVNAME, status);
}
コード例 #7
0
static int ath79_spi_probe(struct platform_device *pdev)
{
	struct spi_master *master;
	struct ath79_spi *sp;
	struct ath79_spi_platform_data *pdata;
	struct resource	*r;
	unsigned long rate;
	int ret;

	master = spi_alloc_master(&pdev->dev, sizeof(*sp));
	if (master == NULL) {
		dev_err(&pdev->dev, "failed to allocate spi master\n");
		return -ENOMEM;
	}

	sp = spi_master_get_devdata(master);
	platform_set_drvdata(pdev, sp);

	pdata = dev_get_platdata(&pdev->dev);

	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
	master->setup = ath79_spi_setup;
	master->cleanup = ath79_spi_cleanup;
	if (pdata) {
		master->bus_num = pdata->bus_num;
		master->num_chipselect = pdata->num_chipselect;
	}

	sp->bitbang.master = spi_master_get(master);
	sp->bitbang.chipselect = ath79_spi_chipselect;
	sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
	sp->bitbang.flags = SPI_CS_HIGH;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (r == NULL) {
		ret = -ENOENT;
		goto err_put_master;
	}

	sp->base = ioremap(r->start, resource_size(r));
	if (!sp->base) {
		ret = -ENXIO;
		goto err_put_master;
	}

	sp->clk = clk_get(&pdev->dev, "ahb");
	if (IS_ERR(sp->clk)) {
		ret = PTR_ERR(sp->clk);
		goto err_unmap;
	}

	ret = clk_enable(sp->clk);
	if (ret)
		goto err_clk_put;

	rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ);
	if (!rate) {
		ret = -EINVAL;
		goto err_clk_disable;
	}

	sp->rrw_delay = ATH79_SPI_RRW_DELAY_FACTOR / rate;
	dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n",
		sp->rrw_delay);

	ath79_spi_enable(sp);
	ret = spi_bitbang_start(&sp->bitbang);
	if (ret)
		goto err_disable;

	return 0;

err_disable:
	ath79_spi_disable(sp);
err_clk_disable:
	clk_disable(sp->clk);
err_clk_put:
	clk_put(sp->clk);
err_unmap:
	iounmap(sp->base);
err_put_master:
	spi_master_put(sp->bitbang.master);

	return ret;
}
コード例 #8
0
/*
 * s3c6410_spi_probe  - probe spi driver
 * @pdev	: platform device struct
 *
 * platform driver member function for probing
 */
static int s3c6410_spi_probe(struct platform_device *pdev)
{
	struct s3c6410_spi *hw;
	struct spi_master *master;
	struct spi_board_info *bi;
	struct resource *res;
	int err = 0;
	int i;
	unsigned int spi_chcfg;

	master = spi_alloc_master(&pdev->dev, sizeof(struct s3c6410_spi));
	if (master == NULL) {
		dev_err(&pdev->dev, "No memory for spi_master\n");
		err = -ENOMEM;
		goto err_nomem;
	}

	hw = spi_master_get_devdata(master);
	memset(hw, 0, sizeof(struct s3c6410_spi));

	hw->master = spi_master_get(master);
	hw->master->num_chipselect = 2;
	hw->pdata = pdev->dev.platform_data;
	hw->dev = &pdev->dev;
	hw->id = pdev->id;

	if (hw->pdata == NULL) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		err = -ENOENT;
		goto err_no_pdata;
	}

	platform_set_drvdata(pdev, hw);

	/* setup the state for the bitbang driver */
	hw->bitbang.master         = hw->master;
	hw->bitbang.setup_transfer = s3c6410_spi_setupxfer;
	hw->bitbang.chipselect     = s3c6410_spi_chipsel;
	hw->bitbang.txrx_bufs      = s3c6410_spi_txrx;
	hw->bitbang.master->setup  = s3c6410_spi_setup;
	
	init_completion(&hw->done);

	/* find and map our resources */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
		err = -ENOENT;
		goto err_no_iores;
	}

	hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1,
					pdev->name);

	if (hw->ioarea == NULL) {
		dev_err(&pdev->dev, "Cannot reserve region\n");
		err = -ENXIO;
		goto err_no_iores;
	}

	hw->regs = ioremap(res->start, (res->end - res->start)+1);
	hw->regs += 0x1000 * hw->id;


	if (hw->regs == NULL) {
		dev_err(&pdev->dev, "Cannot map IO\n");
		err = -ENXIO;
		goto err_no_iomap;
	}

	hw->irq = platform_get_irq(pdev, 0);
	if (hw->irq < 0) {
		dev_err(&pdev->dev, "No IRQ specified\n");
		err = -ENOENT;
		goto err_no_irq;
	}

	err = request_irq(hw->irq, s3c6410_spi_irq, IRQF_DISABLED, pdev->name, hw);
	if (err) {
		dev_err(&pdev->dev, "Cannot claim IRQ\n");
		goto err_no_irq;
	}

	hw->clk = clk_get(&pdev->dev, "spi");
	if (IS_ERR(hw->clk)) {
		dev_err(&pdev->dev, "No clock for device\n");
		err = PTR_ERR(hw->clk);
		goto err_no_clk;
	}

	printk("S3C6410 SPI Driver at 0x%x, irq %d\n", (unsigned int)hw->regs, hw->irq);

	/* for the moment, permanently enable the clock */
#ifdef CONFIG_SPICLK_PCLK
	clk_enable(hw->clk);
	hw->in_clk = clk_get_rate(hw->clk);
#elif defined (CONFIG_SPICLK_EPLL)
	writel((readl(S3C_PCLK_GATE)|S3C_CLKCON_PCLK_SPI0|S3C_CLKCON_PCLK_SPI1),S3C_PCLK_GATE);
	writel((readl(S3C_SCLK_GATE)|S3C_CLKCON_SCLK_SPI0|S3C_CLKCON_SCLK_SPI1),S3C_SCLK_GATE);

	writel(readl(S3C_CLK_SRC)|S3C_CLKSRC_MPLL_CLKSEL, S3C_CLK_SRC);

	/* Set SPi Clock to MOUT(266Mhz)*/
	if(hw->id == 0)		/* SPI_CHANNEL = 0 */
		writel((readl(S3C_CLK_SRC)&~(0x3<<14))|(1<<14), S3C_CLK_SRC);
	else  				/* SPI_CHANNEL = 1 */
		writel((readl(S3C_CLK_SRC)&~(0x3<<16))|(1<<16), S3C_CLK_SRC);

	/* CLK_DIV2 setting */
	/* SPI Input Clock(88.87Mhz) = 266.66Mhz / (2 + 1)*/
	writel(((readl(S3C_CLK_DIV2) & ~(0xff << 0)) | 2) , S3C_CLK_DIV2);

	hw->in_clk = 266660000;

#elif defined (CONFIG_SPICLK_USBCLK)
	writel((readl(S3C_PCLK_GATE)| S3C_CLKCON_PCLK_SPI0|S3C_CLKCON_PCLK_SPI1),S3C_PCLK_GATE);
	writel((readl(S3C_SCLK_GATE)|S3C_CLKCON_SCLK_SPI0_48|S3C_CLKCON_SCLK_SPI1_48),S3C_SCLK_GATE);
	hw->in_clk = 48000000;
#endif
	
	printk("SPI: Source Clock = %ldMhz\n", hw->in_clk);

	/* initialize the gpio */
	if (hw->id == 0) {
		s3c_gpio_cfgpin(S3C64XX_GPC(0), S3C64XX_GPC0_SPI_MISO0);
		s3c_gpio_cfgpin(S3C64XX_GPC(1), S3C64XX_GPC1_SPI_CLK0);
		s3c_gpio_cfgpin(S3C64XX_GPC(2), S3C64XX_GPC2_SPI_MOSI0);
		s3c_gpio_cfgpin(S3C64XX_GPC(3), S3C64XX_GPC3_SPI_nCS0);

		s3c_gpio_setpull(S3C64XX_GPC(0), S3C_GPIO_PULL_UP);
		s3c_gpio_setpull(S3C64XX_GPC(1), S3C_GPIO_PULL_UP);
		s3c_gpio_setpull(S3C64XX_GPC(2), S3C_GPIO_PULL_UP);
		s3c_gpio_setpull(S3C64XX_GPC(3), S3C_GPIO_PULL_UP);
	} else {
		s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_SPI_MISO1);
		s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_SPI_CLK1);
		s3c_gpio_cfgpin(S3C64XX_GPC(6), S3C64XX_GPC6_SPI_MOSI1);
		s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_SPI_nCS1);

		s3c_gpio_setpull(S3C64XX_GPC(4), S3C_GPIO_PULL_UP);
		s3c_gpio_setpull(S3C64XX_GPC(5), S3C_GPIO_PULL_UP);
		s3c_gpio_setpull(S3C64XX_GPC(6), S3C_GPIO_PULL_UP);
		s3c_gpio_setpull(S3C64XX_GPC(7), S3C_GPIO_PULL_UP);
	}

	/* SW Reset */	
	writel(readl(hw->regs + S3C_CH_CFG) | SPI_CH_SW_RST, hw->regs + S3C_CH_CFG);
	udelay(100);
	writel(readl(hw->regs + S3C_CH_CFG) & (~SPI_CH_SW_RST), hw->regs + S3C_CH_CFG);
	udelay(100);

	/* disable  SPI Interrupt */
	writel(SPI_INT_ALL_DISABLE, hw->regs + S3C_SPI_INT_EN);

	/* Set transfer type (CPOL & CPHA set) */
	spi_chcfg = readl(hw->regs + S3C_CH_CFG);
	spi_chcfg &= ~SPI_CH_HSPD_EN;
	spi_chcfg |= SPI_CH_FORMAT_B | SPI_CH_RISING | SPI_CH_MASTER; 
	writel(spi_chcfg, hw->regs + S3C_CH_CFG);

	/* Set NSSOUT to start high after Reset */
	s3c6410_spi_set_cs(hw, BITBANG_CS_INACTIVE);

	/* register our spi controller */
	err = spi_bitbang_start(&hw->bitbang);
	if (err) {
		dev_err(&pdev->dev, "Failed to register SPI master\n");
		goto err_register;
	}

	/* register all the devices associated */
	bi = hw->pdata->board_info;
	for (i = 0; i < hw->pdata->board_size; i++, bi++) {
		dev_info(hw->dev, "registering %s\n", bi->modalias);

		bi->controller_data = hw;
		spi_new_device(master, bi);
	}
	
	/* for suspend & resume */
	test_hw = hw;

	return 0;

 err_register:
	clk_disable(hw->clk);
	clk_put(hw->clk);

 err_no_clk:
	free_irq(hw->irq, hw);

 err_no_irq:
	iounmap(hw->regs);

 err_no_iomap:
	release_resource(hw->ioarea);
	kfree(hw->ioarea);

 err_no_iores:
 err_no_pdata:
	spi_master_put(hw->master);;

 err_nomem:
	return err;
}
コード例 #9
0
static void butterfly_attach(struct parport *p)
{
	struct pardevice	*pd;
	int			status;
	struct butterfly	*pp;
	struct spi_master	*master;
	struct platform_device	*pdev;

	if (butterfly)
		return;

	/* REVISIT:  this just _assumes_ a butterfly is there ... no probe,
	 * and no way to be selective about what it binds to.
	 */

	/* FIXME where should master->cdev.dev come from?
	 * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc
	 * setting up a platform device like this is an ugly kluge...
	 */
	pdev = platform_device_register_simple("butterfly", -1, NULL, 0);

	master = spi_alloc_master(&pdev->dev, sizeof *pp);
	if (!master) {
		status = -ENOMEM;
		goto done;
	}
	pp = spi_master_get_devdata(master);

	/*
	 * SPI and bitbang hookup
	 *
	 * use default setup(), cleanup(), and transfer() methods; and
	 * only bother implementing mode 0.  Start it later.
	 */
	master->bus_num = 42;
	master->num_chipselect = 2;

	pp->bitbang.master = spi_master_get(master);
	pp->bitbang.chipselect = butterfly_chipselect;
	pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0;

	/*
	 * parport hookup
	 */
	pp->port = p;
	pd = parport_register_device(p, "spi_butterfly",
			NULL, NULL, NULL,
			0 /* FLAGS */, pp);
	if (!pd) {
		status = -ENOMEM;
		goto clean0;
	}
	pp->pd = pd;

	status = parport_claim(pd);
	if (status < 0)
		goto clean1;

	/*
	 * Butterfly reset, powerup, run firmware
	 */
	pr_debug("%s: powerup/reset Butterfly\n", p->name);

	/* nCS for dataflash (this bit is inverted on output) */
	parport_frob_control(pp->port, spi_cs_bit, 0);

	/* stabilize power with chip in reset (nRESET), and
	 * both spi_sck_bit and usi_sck_bit clear (CPOL=0)
	 */
	pp->lastbyte |= vcc_bits;
	parport_write_data(pp->port, pp->lastbyte);
	msleep(5);

	/* take it out of reset; assume long reset delay */
	pp->lastbyte |= butterfly_nreset;
	parport_write_data(pp->port, pp->lastbyte);
	msleep(100);


	/*
	 * Start SPI ... for now, hide that we're two physical busses.
	 */
	status = spi_bitbang_start(&pp->bitbang);
	if (status < 0)
		goto clean2;

	/* Bus 1 lets us talk to at45db041b (firmware disables AVR)
	 * or AVR (firmware resets at45, acts as spi slave)
	 */
	pp->info[0].max_speed_hz = 15 * 1000 * 1000;
	strcpy(pp->info[0].modalias, "mtd_dataflash");
	pp->info[0].platform_data = &flash;
	pp->info[0].chip_select = 1;
	pp->info[0].controller_data = pp;
	pp->dataflash = spi_new_device(pp->bitbang.master, &pp->info[0]);
	if (pp->dataflash)
		pr_debug("%s: dataflash at %s\n", p->name,
				pp->dataflash->dev.bus_id);

#ifdef	HAVE_USI
	/* even more custom AVR firmware */
	pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000;
	strcpy(pp->info[1].modalias, "butterfly");
	// pp->info[1].platform_data = ... TBD ... ;
	pp->info[1].chip_select = 2,
	pp->info[1].controller_data = pp;
	pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]);
	if (pp->butterfly)
		pr_debug("%s: butterfly at %s\n", p->name,
				pp->butterfly->dev.bus_id);

	/* FIXME setup ACK for the IRQ line ...  */
#endif

	// dev_info(_what?_, ...)
	pr_info("%s: AVR Butterfly\n", p->name);
	butterfly = pp;
	return;

clean2:
	/* turn off VCC */
	parport_write_data(pp->port, 0);

	parport_release(pp->pd);
clean1:
	parport_unregister_device(pd);
clean0:
	(void) spi_master_put(pp->bitbang.master);
done:
	platform_device_unregister(pdev);
	pr_debug("%s: butterfly probe, fail %d\n", p->name, status);
}
コード例 #10
0
ファイル: spi_s3c64xx_gpio.c プロジェクト: kzlin129/tt-gpl
static int s3c64xx_spigpio_probe(struct platform_device *dev)
{
	struct s3c2410_spigpio_info *info;
	struct spi_master	*master;
	struct s3c64xx_spigpio 	*spi;

	int ret;
	int i;

	master = spi_alloc_master(&dev->dev, sizeof(struct s3c64xx_spigpio));
	if (master == NULL) {
		dev_err(&dev->dev, "failed to allocate spi master\n");
		ret = -ENOMEM;
		goto err;
	}

	spi = spi_master_get_devdata(master);

	/* copy in the platform data */
	info = spi->info = dev->dev.platform_data;

	/* setup spi bitbang adaptor */
	spi->bitbang.master = spi_master_get(master);
	spi->bitbang.master->bus_num = info->bus_num;
	spi->bitbang.master->num_chipselect=0xFFFF;

	spi->bitbang.chipselect = s3c64xx_spigpio_chipselect;


	spi->bitbang.txrx_word[SPI_MODE_0] = s3c64xx_spigpio_txrx_mode0;
	spi->bitbang.txrx_word[SPI_MODE_1] = s3c64xx_spigpio_txrx_mode1;
	spi->bitbang.txrx_word[SPI_MODE_2] = s3c64xx_spigpio_txrx_mode2;
	spi->bitbang.txrx_word[SPI_MODE_3] = s3c64xx_spigpio_txrx_mode3;

	/* set state of spi pins. */
	gpio_direction_output(info->pin_clk, 0);
	s3c_gpio_cfgpin(info->pin_clk, S3C_GPIO_OUTPUT);

	ret = spi_bitbang_start(&spi->bitbang);
	if (ret)
		goto err_no_bitbang;

	/* register the chips to go with the board */
	for (i = 0; i < spi->info->board_size; i++) {
		struct spi_device *spidev;

		dev_info(&dev->dev, "registering %p: %s\n",
			 &spi->info->board_info[i],
			 spi->info->board_info[i].modalias);

		spi->info->board_info[i].controller_data = spi;
		spidev = spi_new_device(master, spi->info->board_info + i);
		if (spidev)
			spidev->max_speed_hz =
					  spi->info->board_info[i].max_speed_hz;
	}

	return 0;

 err_no_bitbang:
	spi_master_put(spi->bitbang.master);
 err:
	return ret;
}
コード例 #11
0
ファイル: spi-nuc970-p0.c プロジェクト: mfkiwl/linux-3.10.y
static int nuc970_spi0_probe(struct platform_device *pdev)
{
	struct nuc970_spi *hw;
	struct spi_master *master;
	int err = 0;
	struct pinctrl *p;

	master = spi_alloc_master(&pdev->dev, sizeof(struct nuc970_spi));
	if (master == NULL) {
		dev_err(&pdev->dev, "No memory for spi_master\n");
		err = -ENOMEM;
		goto err_nomem;
	}

	hw = spi_master_get_devdata(master);
	hw->master = spi_master_get(master);
	hw->pdata  = pdev->dev.platform_data;
	hw->dev = &pdev->dev;

	if (hw->pdata == NULL) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		err = -ENOENT;
		goto err_pdata;
	}

	platform_set_drvdata(pdev, hw);
	init_completion(&hw->done);

#if defined(CONFIG_SPI_NUC970_P0_NORMAL)
	master->mode_bits          = (SPI_MODE_0 | SPI_TX_DUAL | SPI_RX_DUAL | SPI_CS_HIGH | SPI_LSB_FIRST);
#elif defined(CONFIG_SPI_NUC970_P0_QUAD)
    master->mode_bits          = (SPI_MODE_0 | SPI_TX_DUAL | SPI_RX_DUAL | SPI_TX_QUAD | SPI_RX_QUAD | SPI_CS_HIGH | SPI_LSB_FIRST);
#endif
	master->num_chipselect     = hw->pdata->num_cs;
	master->bus_num            = hw->pdata->bus_num;
	hw->bitbang.master         = hw->master;
	hw->bitbang.setup_transfer = nuc970_spi0_setupxfer;
	hw->bitbang.chipselect     = nuc970_spi0_chipsel;
	hw->bitbang.txrx_bufs      = nuc970_spi0_txrx;
	hw->bitbang.master->setup  = nuc970_spi0_setup;

	hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (hw->res == NULL) {
		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
		err = -ENOENT;
		goto err_pdata;
	}

	hw->ioarea = request_mem_region(hw->res->start,
					resource_size(hw->res), pdev->name);

	if (hw->ioarea == NULL) {
		dev_err(&pdev->dev, "Cannot reserve region\n");
		err = -ENXIO;
		goto err_pdata;
	}

	hw->regs = ioremap(hw->res->start, resource_size(hw->res));
	if (hw->regs == NULL) {
		dev_err(&pdev->dev, "Cannot map IO\n");
		err = -ENXIO;
		goto err_iomap;
	}

	hw->irq = platform_get_irq(pdev, 0);
	if (hw->irq < 0) {
		dev_err(&pdev->dev, "No IRQ specified\n");
		err = -ENOENT;
		goto err_irq;
	}

	err = request_irq(hw->irq, nuc970_spi0_irq, 0, pdev->name, hw);
	if (err) {
		dev_err(&pdev->dev, "Cannot claim IRQ\n");
		goto err_irq;
	}

	hw->clk = clk_get(NULL, "spi0");
	if (IS_ERR(hw->clk)) {
		dev_err(&pdev->dev, "No clock for device\n");
		err = PTR_ERR(hw->clk);
		goto err_clk;
	}
    
#if defined(CONFIG_SPI_NUC970_P0_NORMAL) && !defined(CONFIG_SPI_NUC970_P0_SS1)
    p = devm_pinctrl_get_select(&pdev->dev, "spi0");
#elif defined(CONFIG_SPI_NUC970_P0_NORMAL) && defined(CONFIG_SPI_NUC970_P0_SS1_PB0)
    p = devm_pinctrl_get_select(&pdev->dev, "spi0-ss1-PB");
#elif defined(CONFIG_SPI_NUC970_P0_NORMAL) && defined(CONFIG_SPI_NUC970_P0_SS1_PH12)
    p = devm_pinctrl_get_select(&pdev->dev, "spi0-ss1-PH");
#elif defined(CONFIG_SPI_NUC970_P0_QUAD) && !defined(CONFIG_SPI_NUC970_P0_SS1)
	p = devm_pinctrl_get_select(&pdev->dev, "spi0-quad");	
#elif defined(CONFIG_SPI_NUC970_P0_QUAD) && defined(CONFIG_SPI_NUC970_P0_SS1_PB0)
    p = devm_pinctrl_get_select(&pdev->dev, "spi0-quad-ss1-PB");
#elif defined(CONFIG_SPI_NUC970_P0_QUAD) && defined(CONFIG_SPI_NUC970_P0_SS1_PH12)
    p = devm_pinctrl_get_select(&pdev->dev, "spi0-quad-ss1-PB");
#endif
    if(IS_ERR(p)) { 
        dev_err(&pdev->dev, "unable to reserve spi pin by mode\n");
        err = PTR_ERR(p);
    }
    
	nuc970_init_spi(hw);

	err = spi_bitbang_start(&hw->bitbang);
	if (err) {
		dev_err(&pdev->dev, "Failed to register SPI master\n");
		goto err_register;
	}	
	
	return 0;

err_register:
	clk_disable(hw->clk);
	clk_put(hw->clk);
err_clk:
	free_irq(hw->irq, hw);
err_irq:
	iounmap(hw->regs);
err_iomap:
	release_mem_region(hw->res->start, resource_size(hw->res));
	kfree(hw->ioarea);
err_pdata:
	spi_master_put(hw->master);

err_nomem:
	return err;
}
コード例 #12
0
static int __init xilinx_spi_of_probe(struct of_device *ofdev,
					const struct of_device_id *match)
{
	struct spi_master *master;
	struct xilinx_spi *xspi;
	struct resource r_irq_struct;
	struct resource r_mem_struct;

	struct resource *r_irq = &r_irq_struct;
	struct resource *r_mem = &r_mem_struct;
	int rc = 0;
	const u32 *prop;
	int len;

	/* Get resources(memory, IRQ) associated with the device */
	master = spi_alloc_master(&ofdev->dev, sizeof(struct xilinx_spi));

	if (master == NULL) {
		return -ENOMEM;
	}

	dev_set_drvdata(&ofdev->dev, master);

	rc = of_address_to_resource(ofdev->node, 0, r_mem);
	if (rc) {
		dev_warn(&ofdev->dev, "invalid address\n");
		goto put_master;
	}

	rc = of_irq_to_resource(ofdev->node, 0, r_irq);
	if (rc == NO_IRQ) {
		dev_warn(&ofdev->dev, "no IRQ found\n");
		goto put_master;
	}

	xspi = spi_master_get_devdata(master);
	xspi->bitbang.master = spi_master_get(master);
	xspi->bitbang.chipselect = xilinx_spi_chipselect;
	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
	xspi->bitbang.master->setup = xilinx_spi_setup;
	xspi->bitbang.flags |= SPI_SLAVE;
	init_completion(&xspi->done);
	xspi->rx_ptr = xspi->slave_rx_buf;

	xspi->irq = r_irq->start;

	if (!request_mem_region(r_mem->start,
			r_mem->end - r_mem->start + 1, XILINX_SPI_NAME)) {
		rc = -ENXIO;
		dev_warn(&ofdev->dev, "memory request failure\n");
		goto put_master;
	}

	xspi->regs = ioremap(r_mem->start, r_mem->end - r_mem->start + 1);
	if (xspi->regs == NULL) {
		rc = -ENOMEM;
		dev_warn(&ofdev->dev, "ioremap failure\n");
		goto release_mem;
	}
	xspi->irq = r_irq->start;

	/* dynamic bus assignment */
	master->bus_num = -1;

	/* number of slave select bits is required */
	prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len);
	if (!prop || len < sizeof(*prop)) {
		dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
		goto unmap_io;
	}
	master->num_chipselect = *prop;

	/* SPI controller initializations */
	xspi_init_hw(xspi);

	/* Register for SPI Interrupt */
	rc = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi);
	if (rc != 0) {
		dev_warn(&ofdev->dev, "irq request failure: %d\n", xspi->irq);
		goto unmap_io;
	}

	rc = spi_bitbang_start(&xspi->bitbang);
	if (rc != 0) {
		dev_err(&ofdev->dev, "spi_bitbang_start FAILED\n");
		goto free_irq;
	}

	dev_info(&ofdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n",
			(unsigned int)r_mem->start, (u32)xspi->regs, xspi->irq);

	/* Add any subnodes on the SPI bus */
	of_register_spi_devices(master, ofdev->node);

	return rc;

free_irq:
	free_irq(xspi->irq, xspi);
unmap_io:
	iounmap(xspi->regs);
release_mem:
	release_mem_region(r_mem->start, resource_size(r_mem));
put_master:
	spi_master_put(master);
	return rc;
}
コード例 #13
0
ファイル: spi_ubicom32_gpio.c プロジェクト: 7LK/McWRT
/*
 * ubicom32_spi_gpio_probe
 */
static int ubicom32_spi_gpio_probe(struct platform_device *dev)
{
	struct ubicom32_spi_gpio_platform_data *pdata;
	struct spi_master *master;
	struct ubicom32_spi_gpio *usg;
	int ret;

	master = spi_alloc_master(&dev->dev, sizeof(struct ubicom32_spi_gpio));
	if (master == NULL) {
		dev_err(&dev->dev, "failed to allocate spi master\n");
		ret = -ENOMEM;
		goto err;
	}

	usg = (struct ubicom32_spi_gpio *)spi_master_get_devdata(master);

	platform_set_drvdata(dev, usg);

	/*
	 * Copy in the platform data
	 */
	pdata = dev->dev.platform_data;
	usg->pdata = dev->dev.platform_data;

	/*
	 * Request the GPIO lines
	 */
	ret = gpio_request(pdata->pin_mosi, "spi-mosi");
	if (ret) {
		dev_err(&dev->dev, "Failed to allocate spi-mosi GPIO\n");
		goto err;
	}

	ret = gpio_request(pdata->pin_miso, "spi-miso");
	if (ret) {
		dev_err(&dev->dev, "Failed to allocate spi-miso GPIO\n");
		goto err_nomiso;
	}

	ret = gpio_request(pdata->pin_clk, "spi-clk");
	if (ret) {
		dev_err(&dev->dev, "Failed to allocate spi-clk GPIO\n");
		goto err_noclk;
	}

	/*
	 * Setup spi-bitbang adaptor
	 */
	usg->bitbang.flags |= SPI_CS_HIGH;
	usg->bitbang.master = spi_master_get(master);
	usg->bitbang.master->bus_num = pdata->bus_num;
	usg->bitbang.master->num_chipselect = pdata->num_chipselect;
	usg->bitbang.chipselect = ubicom32_spi_gpio_chipselect;

	usg->bitbang.txrx_word[SPI_MODE_0] = ubicom32_spi_gpio_txrx_mode0;
	usg->bitbang.txrx_word[SPI_MODE_1] = ubicom32_spi_gpio_txrx_mode1;
	usg->bitbang.txrx_word[SPI_MODE_2] = ubicom32_spi_gpio_txrx_mode2;
	usg->bitbang.txrx_word[SPI_MODE_3] = ubicom32_spi_gpio_txrx_mode3;

	/*
	 * Setup the GPIO pins
	 */
	gpio_direction_output(pdata->pin_clk, pdata->clk_default);
	gpio_direction_output(pdata->pin_mosi, 0);
	gpio_direction_input(pdata->pin_miso);

	/*
	 * Ready to go
	 */
	ret = spi_bitbang_start(&usg->bitbang);
	if (ret) {
		goto err_no_bitbang;
	}

	return 0;

err_no_bitbang:
	spi_master_put(usg->bitbang.master);

	gpio_free(pdata->pin_clk);

err_noclk:
	gpio_free(pdata->pin_miso);

err_nomiso:
	gpio_free(pdata->pin_mosi);

err:
	return ret;
}
コード例 #14
0
ファイル: spi-ixp4xx-gw2355.c プロジェクト: janfj/dd-wrt
static int spi_gpio_probe(struct platform_device *pdev)
{
	struct spi_master *master;
	struct spi_gpio_platform_data *pdata;
	struct spi_gpio *sp;
	struct spi_device *spidev;
	int err;

	pdata = pdev->dev.platform_data;
	if (!pdata)
		return -ENXIO;

	err = -ENOMEM;
	master = spi_alloc_master(&pdev->dev, sizeof(struct spi_gpio));
	if (!master)
		goto err_alloc_master;

	sp = spi_master_get_devdata(master);
	platform_set_drvdata(pdev, sp);
	sp->info = pdata;


	sp->bitbang.master = spi_master_get(master);
	sp->bitbang.master->bus_num = -1;
	sp->bitbang.master->num_chipselect = 1;
	sp->bitbang.chipselect = spi_gpio_chipselect;
	sp->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_mode0;
	sp->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_mode1;
	sp->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_mode2;
	sp->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_mode3;

//	gpio_direction_output(pdata->pin_cs, pdata->cs_activelow ? 1 : 0);
	gpio_line_config(pdata->pin_cs, IXP4XX_GPIO_OUT);
	gpio_line_config(pdata->pin_clk, IXP4XX_GPIO_OUT);
	gpio_line_config(pdata->pin_mosi, IXP4XX_GPIO_OUT);
	gpio_line_config(pdata->pin_miso, IXP4XX_GPIO_IN);
	gpio_line_set(pdata->pin_clk, 0);
	gpio_line_set(pdata->pin_mosi, 0);
	gpio_line_set(pdata->pin_cs, pdata->cs_activelow ? 1 : 0);

	err = spi_bitbang_start(&sp->bitbang);
	if (err)
		goto err_no_bitbang;
	err = pdata->boardinfo_setup(&sp->bi, master,
				     pdata->boardinfo_setup_data);
	if (err)
		goto err_bi_setup;
	sp->bi.controller_data = sp;
	spidev = spi_new_device(master, &sp->bi);
	if (!spidev)
		goto err_new_dev;

	return 0;

err_new_dev:
err_bi_setup:
	spi_bitbang_stop(&sp->bitbang);
err_no_bitbang:
	spi_master_put(sp->bitbang.master);
err_request_cs:
err_request_miso:
err_request_mosi:
err_request_clk:
	kfree(master);

err_alloc_master:
	return err;
}
コード例 #15
0
static int nuc900_spi_probe(struct platform_device *pdev)
{
	struct nuc900_spi *hw;
	struct spi_master *master;
	int err = 0;

	master = spi_alloc_master(&pdev->dev, sizeof(struct nuc900_spi));
	if (master == NULL) {
		dev_err(&pdev->dev, "No memory for spi_master\n");
		err = -ENOMEM;
		goto err_nomem;
	}

	hw = spi_master_get_devdata(master);
	hw->master = spi_master_get(master);
	hw->pdata  = dev_get_platdata(&pdev->dev);
	hw->dev = &pdev->dev;

	if (hw->pdata == NULL) {
		dev_err(&pdev->dev, "No platform data supplied\n");
		err = -ENOENT;
		goto err_pdata;
	}

	platform_set_drvdata(pdev, hw);
	init_completion(&hw->done);

	master->mode_bits          = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
	master->num_chipselect     = hw->pdata->num_cs;
	master->bus_num            = hw->pdata->bus_num;
	hw->bitbang.master         = hw->master;
	hw->bitbang.chipselect     = nuc900_spi_chipsel;
	hw->bitbang.txrx_bufs      = nuc900_spi_txrx;

	hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (hw->res == NULL) {
		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
		err = -ENOENT;
		goto err_pdata;
	}

	hw->ioarea = request_mem_region(hw->res->start,
					resource_size(hw->res), pdev->name);

	if (hw->ioarea == NULL) {
		dev_err(&pdev->dev, "Cannot reserve region\n");
		err = -ENXIO;
		goto err_pdata;
	}

	hw->regs = ioremap(hw->res->start, resource_size(hw->res));
	if (hw->regs == NULL) {
		dev_err(&pdev->dev, "Cannot map IO\n");
		err = -ENXIO;
		goto err_iomap;
	}

	hw->irq = platform_get_irq(pdev, 0);
	if (hw->irq < 0) {
		dev_err(&pdev->dev, "No IRQ specified\n");
		err = -ENOENT;
		goto err_irq;
	}

	err = request_irq(hw->irq, nuc900_spi_irq, 0, pdev->name, hw);
	if (err) {
		dev_err(&pdev->dev, "Cannot claim IRQ\n");
		goto err_irq;
	}

	hw->clk = clk_get(&pdev->dev, "spi");
	if (IS_ERR(hw->clk)) {
		dev_err(&pdev->dev, "No clock for device\n");
		err = PTR_ERR(hw->clk);
		goto err_clk;
	}

	mfp_set_groupg(&pdev->dev, NULL);
	nuc900_init_spi(hw);

	err = spi_bitbang_start(&hw->bitbang);
	if (err) {
		dev_err(&pdev->dev, "Failed to register SPI master\n");
		goto err_register;
	}

	return 0;

err_register:
	clk_disable(hw->clk);
	clk_put(hw->clk);
err_clk:
	free_irq(hw->irq, hw);
err_irq:
	iounmap(hw->regs);
err_iomap:
	release_mem_region(hw->res->start, resource_size(hw->res));
	kfree(hw->ioarea);
err_pdata:
	spi_master_put(hw->master);

err_nomem:
	return err;
}
コード例 #16
0
struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
	u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word)
{
	struct spi_master *master;
	struct xilinx_spi *xspi;
	int ret;

	master = spi_alloc_master(dev, sizeof(struct xilinx_spi));
	if (!master)
		return NULL;

	
	master->mode_bits = SPI_CPOL | SPI_CPHA;

	xspi = spi_master_get_devdata(master);
	xspi->bitbang.master = spi_master_get(master);
	xspi->bitbang.chipselect = xilinx_spi_chipselect;
	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
	xspi->bitbang.master->setup = xilinx_spi_setup;
	init_completion(&xspi->done);

	if (!request_mem_region(mem->start, resource_size(mem),
		XILINX_SPI_NAME))
		goto put_master;

	xspi->regs = ioremap(mem->start, resource_size(mem));
	if (xspi->regs == NULL) {
		dev_warn(dev, "ioremap failure\n");
		goto map_failed;
	}

	master->bus_num = bus_num;
	master->num_chipselect = num_cs;
	master->dev.of_node = dev->of_node;

	xspi->mem = *mem;
	xspi->irq = irq;
	if (little_endian) {
		xspi->read_fn = xspi_read32;
		xspi->write_fn = xspi_write32;
	} else {
		xspi->read_fn = xspi_read32_be;
		xspi->write_fn = xspi_write32_be;
	}
	xspi->bits_per_word = bits_per_word;
	if (xspi->bits_per_word == 8) {
		xspi->tx_fn = xspi_tx8;
		xspi->rx_fn = xspi_rx8;
	} else if (xspi->bits_per_word == 16) {
		xspi->tx_fn = xspi_tx16;
		xspi->rx_fn = xspi_rx16;
	} else if (xspi->bits_per_word == 32) {
		xspi->tx_fn = xspi_tx32;
		xspi->rx_fn = xspi_rx32;
	} else
		goto unmap_io;


	
	xspi_init_hw(xspi);

	
	ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi);
	if (ret)
		goto unmap_io;

	ret = spi_bitbang_start(&xspi->bitbang);
	if (ret) {
		dev_err(dev, "spi_bitbang_start FAILED\n");
		goto free_irq;
	}

	dev_info(dev, "at 0x%08llX mapped to 0x%p, irq=%d\n",
		(unsigned long long)mem->start, xspi->regs, xspi->irq);
	return master;

free_irq:
	free_irq(xspi->irq, xspi);
unmap_io:
	iounmap(xspi->regs);
map_failed:
	release_mem_region(mem->start, resource_size(mem));
put_master:
	spi_master_put(master);
	return NULL;
}
コード例 #17
0
ファイル: spi-imx.c プロジェクト: CSCLOG/beaglebone
static int __devinit spi_imx_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	const struct of_device_id *of_id =
			of_match_device(spi_imx_dt_ids, &pdev->dev);
	struct spi_imx_master *mxc_platform_info =
			dev_get_platdata(&pdev->dev);
	struct spi_master *master;
	struct spi_imx_data *spi_imx;
	struct resource *res;
	int i, ret, num_cs;

	if (!np && !mxc_platform_info) {
		dev_err(&pdev->dev, "can't get the platform data\n");
		return -EINVAL;
	}

	ret = of_property_read_u32(np, "fsl,spi-num-chipselects", &num_cs);
	if (ret < 0)
		num_cs = mxc_platform_info->num_chipselect;

	master = spi_alloc_master(&pdev->dev,
			sizeof(struct spi_imx_data) + sizeof(int) * num_cs);
	if (!master)
		return -ENOMEM;

	platform_set_drvdata(pdev, master);

	master->bus_num = pdev->id;
	master->num_chipselect = num_cs;

	spi_imx = spi_master_get_devdata(master);
	spi_imx->bitbang.master = spi_master_get(master);

	for (i = 0; i < master->num_chipselect; i++) {
		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
		if (cs_gpio < 0)
			cs_gpio = mxc_platform_info->chipselect[i];

		spi_imx->chipselect[i] = cs_gpio;
		if (cs_gpio < 0)
			continue;

		ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
		if (ret) {
			while (i > 0) {
				i--;
				if (spi_imx->chipselect[i] >= 0)
					gpio_free(spi_imx->chipselect[i]);
			}
			dev_err(&pdev->dev, "can't get cs gpios\n");
			goto out_master_put;
		}
	}

	spi_imx->bitbang.chipselect = spi_imx_chipselect;
	spi_imx->bitbang.setup_transfer = spi_imx_setupxfer;
	spi_imx->bitbang.txrx_bufs = spi_imx_transfer;
	spi_imx->bitbang.master->setup = spi_imx_setup;
	spi_imx->bitbang.master->cleanup = spi_imx_cleanup;
	spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;

	init_completion(&spi_imx->xfer_done);

	spi_imx->devtype_data = of_id ? of_id->data :
		(struct spi_imx_devtype_data *) pdev->id_entry->driver_data;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "can't get platform resource\n");
		ret = -ENOMEM;
		goto out_gpio_free;
	}

	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
		dev_err(&pdev->dev, "request_mem_region failed\n");
		ret = -EBUSY;
		goto out_gpio_free;
	}

	spi_imx->base = ioremap(res->start, resource_size(res));
	if (!spi_imx->base) {
		ret = -EINVAL;
		goto out_release_mem;
	}

	spi_imx->irq = platform_get_irq(pdev, 0);
	if (spi_imx->irq < 0) {
		ret = -EINVAL;
		goto out_iounmap;
	}

	ret = request_irq(spi_imx->irq, spi_imx_isr, 0, DRIVER_NAME, spi_imx);
	if (ret) {
		dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret);
		goto out_iounmap;
	}

	spi_imx->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(spi_imx->clk)) {
		dev_err(&pdev->dev, "unable to get clock\n");
		ret = PTR_ERR(spi_imx->clk);
		goto out_free_irq;
	}

	clk_enable(spi_imx->clk);
	spi_imx->spi_clk = clk_get_rate(spi_imx->clk);

	spi_imx->devtype_data->reset(spi_imx);

	spi_imx->devtype_data->intctrl(spi_imx, 0);

	master->dev.of_node = pdev->dev.of_node;
	ret = spi_bitbang_start(&spi_imx->bitbang);
	if (ret) {
		dev_err(&pdev->dev, "bitbang start failed with %d\n", ret);
		goto out_clk_put;
	}

	dev_info(&pdev->dev, "probed\n");

	return ret;

out_clk_put:
	clk_disable(spi_imx->clk);
	clk_put(spi_imx->clk);
out_free_irq:
	free_irq(spi_imx->irq, spi_imx);
out_iounmap:
	iounmap(spi_imx->base);
out_release_mem:
	release_mem_region(res->start, resource_size(res));
out_gpio_free:
	for (i = 0; i < master->num_chipselect; i++)
		if (spi_imx->chipselect[i] >= 0)
			gpio_free(spi_imx->chipselect[i]);
out_master_put:
	spi_master_put(master);
	kfree(master);
	platform_set_drvdata(pdev, NULL);
	return ret;
}
コード例 #18
0
static int __devinit tiny_spi_probe(struct platform_device *pdev)
{
	struct tiny_spi_platform_data *platp = pdev->dev.platform_data;
	struct tiny_spi *hw;
	struct spi_master *master;
	struct resource *res;
	unsigned int i;
	int err = -ENODEV;

	master = spi_alloc_master(&pdev->dev, sizeof(struct tiny_spi));
	if (!master)
		return err;

	
	master->bus_num = pdev->id;
	master->num_chipselect = 255;
	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
	master->setup = tiny_spi_setup;

	hw = spi_master_get_devdata(master);
	platform_set_drvdata(pdev, hw);

	
	hw->bitbang.master = spi_master_get(master);
	if (!hw->bitbang.master)
		return err;
	hw->bitbang.setup_transfer = tiny_spi_setup_transfer;
	hw->bitbang.chipselect = tiny_spi_chipselect;
	hw->bitbang.txrx_bufs = tiny_spi_txrx_bufs;

	
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		goto exit_busy;
	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
				     pdev->name))
		goto exit_busy;
	hw->base = devm_ioremap_nocache(&pdev->dev, res->start,
					resource_size(res));
	if (!hw->base)
		goto exit_busy;
	
	hw->irq = platform_get_irq(pdev, 0);
	if (hw->irq >= 0) {
		init_completion(&hw->done);
		err = devm_request_irq(&pdev->dev, hw->irq, tiny_spi_irq, 0,
				       pdev->name, hw);
		if (err)
			goto exit;
	}
	
	if (platp) {
		hw->gpio_cs_count = platp->gpio_cs_count;
		hw->gpio_cs = platp->gpio_cs;
		if (platp->gpio_cs_count && !platp->gpio_cs)
			goto exit_busy;
		hw->freq = platp->freq;
		hw->baudwidth = platp->baudwidth;
	} else {
		err = tiny_spi_of_probe(pdev);
		if (err)
			goto exit;
	}
	for (i = 0; i < hw->gpio_cs_count; i++) {
		err = gpio_request(hw->gpio_cs[i], dev_name(&pdev->dev));
		if (err)
			goto exit_gpio;
		gpio_direction_output(hw->gpio_cs[i], 1);
	}
	hw->bitbang.master->num_chipselect = max(1U, hw->gpio_cs_count);

	
	err = spi_bitbang_start(&hw->bitbang);
	if (err)
		goto exit;
	dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq);

	return 0;

exit_gpio:
	while (i-- > 0)
		gpio_free(hw->gpio_cs[i]);
exit_busy:
	err = -EBUSY;
exit:
	platform_set_drvdata(pdev, NULL);
	spi_master_put(master);
	return err;
}