Esempio n. 1
0
struct platform_device *__init
at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
{
	struct platform_device		*pdev;
	struct mci_dma_data	        *slave;
	u32				pioa_mask;
	u32				piob_mask;

	if (id != 0 || !data)
		return NULL;

	/* Must have at least one usable slot */
	if (!data->slot[0].bus_width && !data->slot[1].bus_width)
		return NULL;

	pdev = platform_device_alloc("atmel_mci", id);
	if (!pdev)
		goto fail;

	if (platform_device_add_resources(pdev, atmel_mci0_resource,
				ARRAY_SIZE(atmel_mci0_resource)))
		goto fail;

	slave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL);
	if (!slave)
		goto fail;

	slave->sdata.dma_dev = &dw_dmac0_device.dev;
	slave->sdata.cfg_hi = (DWC_CFGH_SRC_PER(0)
				| DWC_CFGH_DST_PER(1));
	slave->sdata.cfg_lo &= ~(DWC_CFGL_HS_DST_POL
				| DWC_CFGL_HS_SRC_POL);

	data->dma_slave = slave;

	if (platform_device_add_data(pdev, data,
				sizeof(struct mci_platform_data)))
		goto fail_free;

	/* CLK line is common to both slots */
	pioa_mask = 1 << 10;

	switch (data->slot[0].bus_width) {
	case 4:
		pioa_mask |= 1 << 13;		/* DATA1 */
		pioa_mask |= 1 << 14;		/* DATA2 */
		pioa_mask |= 1 << 15;		/* DATA3 */
		/* fall through */
	case 1:
		pioa_mask |= 1 << 11;		/* CMD	 */
		pioa_mask |= 1 << 12;		/* DATA0 */

		if (gpio_is_valid(data->slot[0].detect_pin))
			at32_select_gpio(data->slot[0].detect_pin, 0);
		if (gpio_is_valid(data->slot[0].wp_pin))
			at32_select_gpio(data->slot[0].wp_pin, 0);
		break;
	case 0:
		/* Slot is unused */
		break;
	default:
		goto fail_free;
	}

	select_peripheral(PIOA, pioa_mask, PERIPH_A, 0);
	piob_mask = 0;

	switch (data->slot[1].bus_width) {
	case 4:
		piob_mask |= 1 <<  8;		/* DATA1 */
		piob_mask |= 1 <<  9;		/* DATA2 */
		piob_mask |= 1 << 10;		/* DATA3 */
		/* fall through */
	case 1:
		piob_mask |= 1 <<  6;		/* CMD	 */
		piob_mask |= 1 <<  7;		/* DATA0 */
		select_peripheral(PIOB, piob_mask, PERIPH_B, 0);

		if (gpio_is_valid(data->slot[1].detect_pin))
			at32_select_gpio(data->slot[1].detect_pin, 0);
		if (gpio_is_valid(data->slot[1].wp_pin))
			at32_select_gpio(data->slot[1].wp_pin, 0);
		break;
	case 0:
		/* Slot is unused */
		break;
	default:
		if (!data->slot[0].bus_width)
Esempio n. 2
0
int imapx200_dma_devconfig(int channel,
                           enum imapx200_dmafc source,
                           unsigned long devaddr)
{
    struct imapx200_dma_chan *chan = imap_dma_lookup_channel(channel);
    u32 peripheral;
    u32 ctlx = 0;
    u32 intrx = 0;
    u32 cfg_hi = 0;
    u32 cfg_lo = 0;

    pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
             __func__, channel, source, devaddr, chan);

    WARN_ON(!chan);
    if (!chan)
        return -EINVAL;

    peripheral = (chan->peripheral & 0x7);
    chan->source = source;
    chan->dev_addr = devaddr;

    pr_debug("%s: peripheral %d\n", __func__, peripheral);
    ctlx = chan_readl(chan,CTL_LO);
    pr_debug("devconfig_1\n");
    ctlx &= ~DWC_CTLL_FC_MASK;
    cfg_hi = chan_readl(chan,CFG_HI);
    pr_debug("CFG_HI is %x\n", cfg_hi);
    cfg_lo = chan_readl(chan,CFG_LO);
    pr_debug("devconfig_3\n");
    switch (source) {
    case IMAPX200_DMA_M2M:
        ctlx |= DWC_CTLL_FC_M2M;
        break;
    case IMAPX200_DMA_M2P:
        ctlx |= DWC_CTLL_FC_M2P;
        cfg_lo &= ~DWC_CFGL_HS_DST;
        cfg_hi |= DWC_CFGH_DST_PER(chan->client->handshake);
        break;
    case IMAPX200_DMA_P2M:
        ctlx |= DWC_CTLL_FC_P2M;
        cfg_lo &= ~DWC_CFGL_HS_SRC;
        cfg_hi |= DWC_CFGH_SRC_PER(chan->client->handshake);
        break;
    default:
        printk(KERN_ERR "%s: bad source\n", __func__);
        return -EINVAL;
    }
    /*set dma flow control bit*/
    chan_writel(chan,CTL_LO,ctlx);
    pr_debug("devconfig_4\n");
    chan_writel(chan,CFG_LO,cfg_lo);
    pr_debug("devconfig_5\n");
    chan_writel(chan,CFG_HI,cfg_hi);
//	cfg_hi = chan_readl(chan,CFG_HI);
//	pr_debug("CFG_HI is %x\n", cfg_hi);
    /* allow TC and ERR interrupts */
    intrx = 1<<(chan->number);
    pr_debug("devconfig_6\n");
    dma_set_bit(chan->dmac,MASK.XFER,intrx);
    pr_debug("devconfig_7\n");
    dma_set_bit(chan->dmac,MASK.BLOCK,intrx);
    dma_set_bit(chan->dmac,MASK.ERROR,intrx);

    pr_debug("devconfig_8\n");
    return 0;
}