Main Page | Directories | File List | Globals

dma.c

Go to the documentation of this file.
00001 /*
00002  * kernel_drivers/adi_chips/dma.c
00003  *
00004  * Copyright (c) 2003-2004 Lukasz Dembinski <dembol@nasa.com.pl>
00005  * All Rights Reserved
00006  * 
00007  * Date:        2004/10
00008  * Author:      Lukasz Dembinski
00009  * Info:        dma.c core file
00010  * Contact:     mailto: <dembol@nasa.com.pl>
00011  *
00012  */
00013 #include <agnix/agnix.h>
00014 #include <agnix/adi/adi.h>
00015 #include <agnix/spinlock.h>
00016 #include <asm/types.h>
00017 #include <agnix/ioport.h>
00018 #include <agnix/memory.h>
00019 #include <agnix/resources.h>
00020 #include <agnix/console.h>
00021 
00022 #define MOD_NAME        "DMA: "
00023 
00024 u32 dma_resource_bitmap[1];
00025 
00026 struct resource_s dma_resource = {
00027     .resource_name      = "DMA",
00028     .resource_bitmap    = dma_resource_bitmap,
00029     .resource_len       = 1,
00030     .resource_max       = DMA_MAX_CHANNEL
00031 };
00032 
00033 int dma_resource_desc;
00034 u32 flags;
00035 
00036 int dma_chip_init(struct chip_s *chip)
00037 {
00038     if ((dma_resource_desc = register_resource(&dma_resource)) < 0)
00039     {
00040         printk(MOD_NAME "can not register dma resource\n");
00041         return -1;
00042     }    
00043     
00044     return 0;
00045 }
00046 
00047 int dma_chip_release(struct chip_s *chip)
00048 {
00049     return 0;
00050 }
00051 
00052 int dma_request_channel(struct chip_s *chip, u8 dma_nr)
00053 {
00054     return request_resource(dma_resource_desc, (int)dma_nr);
00055 }
00056 
00057 int dma_put_channel(struct chip_s *chip, u8 dma_nr)
00058 {
00059     return put_free_resource(dma_resource_desc, (int)dma_nr);
00060 }
00061 
00062 int dma_enable(struct chip_s *chip, u8 dma_nr)
00063 {
00064     if (dma_nr > 7)
00065         return -1;
00066 
00067     if (dma_nr < 4)
00068         outb(dma_nr, DMA1_REG_MASK);
00069     else
00070     if (dma_nr < 8)
00071         outb(dma_nr & 0x03, DMA2_REG_MASK);
00072 
00073     return 0;
00074 }
00075 
00076 int dma_disable(struct chip_s *chip, u8 dma_nr)
00077 {
00078     if (dma_nr > 7)
00079         return -1;
00080 
00081     if (dma_nr < 4)
00082         outb(dma_nr | 0x04, DMA1_REG_MASK);
00083     else
00084     if (dma_nr < 8)
00085         outb((dma_nr & 0x03) | 0x04, DMA2_REG_MASK);
00086 
00087     return 0;
00088 }
00089 
00090 int dma_clear_ff(struct chip_s *chip, u8 dma_nr)
00091 {
00092     if (dma_nr > 7)
00093         return -1;
00094 
00095     if (dma_nr < 4)
00096         outb(0x00, DMA1_REG_FF);
00097     else
00098     if (dma_nr < 8)
00099         outb(0x00, DMA2_REG_FF);
00100 
00101     return 0;
00102 }
00103 
00104 int dma_set_mode(struct chip_s *chip, u8 dma_nr, u8 mode)
00105 {
00106     if (dma_nr > 7)
00107         return -1;
00108 
00109     if (dma_nr < 4)
00110         outb(dma_nr | mode, DMA1_REG_MODE);
00111     else
00112     if (dma_nr < 8)
00113         outb((dma_nr & 0x03) | mode, DMA2_REG_MODE);
00114 
00115     return 0;
00116 }
00117 
00118 int dma_set_addr(struct chip_s *chip, u8 dma_nr, u32 address)
00119 {
00120     int shift = 0;
00121     u8 page = (u8)(address >> 16);
00122     u8 dma_page_addr;
00123     u8 dma_addr;
00124 
00125     switch(dma_nr) {
00126         case 0x00:
00127             dma_page_addr = DMA_PAGE_0;
00128             break;
00129 
00130         case 0x01:
00131             dma_page_addr = DMA_PAGE_1;
00132             break;
00133 
00134         case 0x02:
00135             dma_page_addr = DMA_PAGE_2;
00136             break;
00137 
00138         case 0x03:
00139             dma_page_addr = DMA_PAGE_3;
00140             break;
00141 
00142         case 0x05:
00143             dma_page_addr = DMA_PAGE_5;
00144             break;
00145 
00146         case 0x06:
00147             dma_page_addr = DMA_PAGE_6;
00148             break;
00149 
00150         case 0x07:
00151             dma_page_addr = DMA_PAGE_7;
00152             break;
00153             
00154         default:
00155             return -1;
00156     }
00157 
00158     if (dma_nr < 4) {
00159         dma_addr = ((dma_nr & 0x03) << 1);
00160     } else 
00161     if (dma_nr < 8) {
00162         page &= 0xfe;
00163         shift = 1;
00164         dma_addr = ((dma_nr & 0x03) << 2);
00165     } else
00166         return -1;
00167 
00168     outb(page, dma_page_addr);
00169     outb((address >> shift) & 0xff, dma_addr);
00170     outb((address >> (8 + shift)) & 0xff, dma_addr);    
00171 
00172     return 0;
00173 }
00174 
00175 int dma_set_count(struct chip_s *chip, u8 dma_nr, u16 count)
00176 {
00177     int shift = 0;
00178     u8 dma_count_addr;
00179     
00180     count--;
00181 
00182     if (dma_nr < 4) {
00183         dma_count_addr = ((dma_nr & 0x03) << 1) + 1;
00184     } else 
00185     if (dma_nr < 8) {
00186         shift = 1;
00187         dma_count_addr = ((dma_nr & 0x03) << 2) + 1;
00188     } else
00189         return -1;
00190 
00191     outb((count >> shift) & 0xff, dma_count_addr);
00192     outb((count >> (8 + shift)) & 0xff, dma_count_addr);    
00193     
00194     return 0;
00195 }
00196 
00197 int dma_lock(struct chip_s *chip)
00198 {
00199     spin_lock_irqsave(&chip->chip_lock, flags);
00200     
00201     return 0;
00202 }
00203 
00204 int dma_unlock(struct chip_s *chip)
00205 {
00206     spin_unlock_irqrestore(&chip->chip_lock, flags);
00207     
00208     return 0;
00209 }
00210 
00211 struct chip_dma_ops_s   dma_internal_ops = 
00212 {
00213     .dma_lock            = dma_lock,
00214     .dma_unlock          = dma_unlock,
00215     .dma_request_channel = dma_request_channel,
00216     .dma_put_channel     = dma_put_channel,
00217     .dma_enable          = dma_enable,
00218     .dma_disable         = dma_disable,
00219     .dma_clear_ff        = dma_clear_ff,
00220     .dma_set_addr        = dma_set_addr,
00221     .dma_set_mode        = dma_set_mode,
00222     .dma_set_count       = dma_set_count
00223 };
00224 
00225 struct chip_ops_s       dma_chip_ops = {
00226     .init               = dma_chip_init,
00227     .release            = dma_chip_release
00228 };
00229 
00230 struct chip_s           dma_chip = {
00231     .chip_name          = "dma",
00232     .chip_class         = CHIP_CLASS_DMA,
00233     .chip_vendor        = 0x8086,
00234     .chip_ops           = &dma_chip_ops,
00235     .chip_pm_ops        = NULL,
00236     .internal_ops       = &dma_internal_ops,
00237 };
00238 
00239 int __init dma_init(void)
00240 {
00241     adi_register_chip(&dma_chip);
00242 
00243     return 0;    
00244 }
Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix