00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 }