|  | @@ -1065,3 +1065,123 @@ int s3c2410_dma_config(enum dma_ch channel,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	case 2:
 | 
	
		
			
				|  |  |  		dcon |= S3C2410_DCON_HALFWORD;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	case 4:
 | 
	
		
			
				|  |  | +		dcon |= S3C2410_DCON_WORD;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		pr_debug("%s: bad transfer size %d\n", __func__, xferunit);
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	dcon |= S3C2410_DCON_HWTRIG;
 | 
	
		
			
				|  |  | +	dcon |= S3C2410_DCON_INTREQ;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pr_debug("%s: dcon now %08x\n", __func__, dcon);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	chan->dcon = dcon;
 | 
	
		
			
				|  |  | +	chan->xfer_unit = xferunit;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +EXPORT_SYMBOL(s3c2410_dma_config);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* s3c2410_dma_devconfig
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * configure the dma source/destination hardware type and address
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * source:    DMA_FROM_DEVICE: source is hardware
 | 
	
		
			
				|  |  | + *            DMA_TO_DEVICE: source is memory
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * devaddr:   physical address of the source
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +int s3c2410_dma_devconfig(enum dma_ch channel,
 | 
	
		
			
				|  |  | +			  enum dma_data_direction source,
 | 
	
		
			
				|  |  | +			  unsigned long devaddr)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
 | 
	
		
			
				|  |  | +	unsigned int hwcfg;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (chan == NULL)
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pr_debug("%s: source=%d, devaddr=%08lx\n",
 | 
	
		
			
				|  |  | +		 __func__, (int)source, devaddr);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	chan->source = source;
 | 
	
		
			
				|  |  | +	chan->dev_addr = devaddr;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	switch (chan->req_ch) {
 | 
	
		
			
				|  |  | +	case DMACH_XD0:
 | 
	
		
			
				|  |  | +	case DMACH_XD1:
 | 
	
		
			
				|  |  | +		hwcfg = 0; /* AHB */
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		hwcfg = S3C2410_DISRCC_APB;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* always assume our peripheral desintation is a fixed
 | 
	
		
			
				|  |  | +	 * address in memory. */
 | 
	
		
			
				|  |  | +	 hwcfg |= S3C2410_DISRCC_INC;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	switch (source) {
 | 
	
		
			
				|  |  | +	case DMA_FROM_DEVICE:
 | 
	
		
			
				|  |  | +		/* source is hardware */
 | 
	
		
			
				|  |  | +		pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
 | 
	
		
			
				|  |  | +			 __func__, devaddr, hwcfg);
 | 
	
		
			
				|  |  | +		dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
 | 
	
		
			
				|  |  | +		dma_wrreg(chan, S3C2410_DMA_DISRC,  devaddr);
 | 
	
		
			
				|  |  | +		dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	case DMA_TO_DEVICE:
 | 
	
		
			
				|  |  | +		/* source is memory */
 | 
	
		
			
				|  |  | +		pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n",
 | 
	
		
			
				|  |  | +			 __func__, devaddr, hwcfg);
 | 
	
		
			
				|  |  | +		dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
 | 
	
		
			
				|  |  | +		dma_wrreg(chan, S3C2410_DMA_DIDST,  devaddr);
 | 
	
		
			
				|  |  | +		dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		printk(KERN_ERR "dma%d: invalid source type (%d)\n",
 | 
	
		
			
				|  |  | +		       channel, source);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (dma_sel.direction != NULL)
 | 
	
		
			
				|  |  | +		(dma_sel.direction)(chan, chan->map, source);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +EXPORT_SYMBOL(s3c2410_dma_devconfig);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* s3c2410_dma_getposition
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * returns the current transfer points for the dma source and destination
 | 
	
		
			
				|  |  | +*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dst)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (chan == NULL)
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (src != NULL)
 | 
	
		
			
				|  |  | + 		*src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + 	if (dst != NULL)
 | 
	
		
			
				|  |  | + 		*dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
 |