diff options
-rw-r--r-- | drivers/staging/comedi/drivers/pcmmio.c | 110 |
1 files changed, 77 insertions, 33 deletions
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index c764b28fb31..35ba93989a3 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c | |||
@@ -713,9 +713,11 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, | |||
713 | byte &= ~(1 << bit_no); | 713 | byte &= ~(1 << bit_no); |
714 | /**< set input channel to '0' */ | 714 | /**< set input channel to '0' */ |
715 | 715 | ||
716 | /* write out byte -- this is the only time we actually affect the | 716 | /* |
717 | hardware as all channels are implicitly output -- but input | 717 | * write out byte -- this is the only time we actually affect |
718 | channels are set to float-high */ | 718 | * the hardware as all channels are implicitly output |
719 | * -- but input channels are set to float-high | ||
720 | */ | ||
719 | outb(byte, ioaddr); | 721 | outb(byte, ioaddr); |
720 | 722 | ||
721 | /* save to io_bits */ | 723 | /* save to io_bits */ |
@@ -769,8 +771,8 @@ static void init_asics(struct comedi_device *dev) | |||
769 | outb(0xff, baseaddr + REG_ENAB0); */ | 771 | outb(0xff, baseaddr + REG_ENAB0); */ |
770 | /* END DEBUG */ | 772 | /* END DEBUG */ |
771 | 773 | ||
772 | switch_page(dev, asic, 0); /* switch back to default page 0 */ | 774 | /* switch back to default page 0 */ |
773 | 775 | switch_page(dev, asic, 0); | |
774 | } | 776 | } |
775 | } | 777 | } |
776 | 778 | ||
@@ -849,7 +851,10 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) | |||
849 | REG_INT_ID0 + port); | 851 | REG_INT_ID0 + port); |
850 | 852 | ||
851 | if (io_lines_with_edges) | 853 | if (io_lines_with_edges) |
852 | /* clear pending interrupt */ | 854 | /* |
855 | * clear pending | ||
856 | * interrupt | ||
857 | */ | ||
853 | outb(0, iobase + | 858 | outb(0, iobase + |
854 | REG_INT_ID0 + | 859 | REG_INT_ID0 + |
855 | port); | 860 | port); |
@@ -868,14 +873,21 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) | |||
868 | 873 | ||
869 | if (triggered) { | 874 | if (triggered) { |
870 | struct comedi_subdevice *s; | 875 | struct comedi_subdevice *s; |
871 | /* TODO here: dispatch io lines to subdevs with commands.. */ | 876 | /* |
877 | * TODO here: dispatch io lines to subdevs | ||
878 | * with commands.. | ||
879 | */ | ||
872 | printk | 880 | printk |
873 | ("PCMMIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", | 881 | ("PCMMIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", |
874 | irq, asic, triggered); | 882 | irq, asic, triggered); |
875 | for (s = dev->subdevices + 2; | 883 | for (s = dev->subdevices + 2; |
876 | s < dev->subdevices + dev->n_subdevices; | 884 | s < dev->subdevices + dev->n_subdevices; |
877 | ++s) { | 885 | ++s) { |
878 | if (subpriv->dio.intr.asic == asic) { /* this is an interrupt subdev, and it matches this asic! */ | 886 | /* |
887 | * this is an interrupt subdev, | ||
888 | * and it matches this asic! | ||
889 | */ | ||
890 | if (subpriv->dio.intr.asic == asic) { | ||
879 | unsigned long flags; | 891 | unsigned long flags; |
880 | unsigned oldevents; | 892 | unsigned oldevents; |
881 | 893 | ||
@@ -910,9 +922,8 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) | |||
910 | n < len; | 922 | n < len; |
911 | n++) { | 923 | n++) { |
912 | ch = CR_CHAN(s->async->cmd.chanlist[n]); | 924 | ch = CR_CHAN(s->async->cmd.chanlist[n]); |
913 | if (mytrig & (1U << ch)) { | 925 | if (mytrig & (1U << ch)) |
914 | val |= (1U << n); | 926 | val |= (1U << n); |
915 | } | ||
916 | } | 927 | } |
917 | /* Write the scan to the buffer. */ | 928 | /* Write the scan to the buffer. */ |
918 | if (comedi_buf_put(s->async, ((short *)&val)[0]) | 929 | if (comedi_buf_put(s->async, ((short *)&val)[0]) |
@@ -920,8 +931,7 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) | |||
920 | comedi_buf_put | 931 | comedi_buf_put |
921 | (s->async, | 932 | (s->async, |
922 | ((short *) | 933 | ((short *) |
923 | &val)[1])) | 934 | &val)[1])) { |
924 | { | ||
925 | s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); | 935 | s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); |
926 | } else { | 936 | } else { |
927 | /* Overflow! Stop acquisition!! */ | 937 | /* Overflow! Stop acquisition!! */ |
@@ -1024,9 +1034,16 @@ static int pcmmio_start_intr(struct comedi_device *dev, | |||
1024 | 1) << subpriv->dio.intr.first_chan; | 1034 | 1) << subpriv->dio.intr.first_chan; |
1025 | subpriv->dio.intr.enabled_mask = bits; | 1035 | subpriv->dio.intr.enabled_mask = bits; |
1026 | 1036 | ||
1027 | { /* the below code configures the board to use a specific IRQ from 0-15. */ | 1037 | { |
1038 | /* | ||
1039 | * the below code configures the board | ||
1040 | * to use a specific IRQ from 0-15. | ||
1041 | */ | ||
1028 | unsigned char b; | 1042 | unsigned char b; |
1029 | /* set resource enable register to enable IRQ operation */ | 1043 | /* |
1044 | * set resource enable register | ||
1045 | * to enable IRQ operation | ||
1046 | */ | ||
1030 | outb(1 << 4, dev->iobase + 3); | 1047 | outb(1 << 4, dev->iobase + 3); |
1031 | /* set bits 0-3 of b to the irq number from 0-15 */ | 1048 | /* set bits 0-3 of b to the irq number from 0-15 */ |
1032 | b = dev->irq & ((1 << 4) - 1); | 1049 | b = dev->irq & ((1 << 4) - 1); |
@@ -1080,14 +1097,12 @@ pcmmio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, | |||
1080 | 1097 | ||
1081 | spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags); | 1098 | spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags); |
1082 | s->async->inttrig = 0; | 1099 | s->async->inttrig = 0; |
1083 | if (subpriv->dio.intr.active) { | 1100 | if (subpriv->dio.intr.active) |
1084 | event = pcmmio_start_intr(dev, s); | 1101 | event = pcmmio_start_intr(dev, s); |
1085 | } | ||
1086 | spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); | 1102 | spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); |
1087 | 1103 | ||
1088 | if (event) { | 1104 | if (event) |
1089 | comedi_event(dev, s); | 1105 | comedi_event(dev, s); |
1090 | } | ||
1091 | 1106 | ||
1092 | return 1; | 1107 | return 1; |
1093 | } | 1108 | } |
@@ -1129,9 +1144,8 @@ static int pcmmio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) | |||
1129 | } | 1144 | } |
1130 | spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); | 1145 | spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); |
1131 | 1146 | ||
1132 | if (event) { | 1147 | if (event) |
1133 | comedi_event(dev, s); | 1148 | comedi_event(dev, s); |
1134 | } | ||
1135 | 1149 | ||
1136 | return 0; | 1150 | return 0; |
1137 | } | 1151 | } |
@@ -1179,17 +1193,32 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, | |||
1179 | short sample, adc_adjust = 0; | 1193 | short sample, adc_adjust = 0; |
1180 | 1194 | ||
1181 | if (chan > 7) | 1195 | if (chan > 7) |
1182 | chan -= 8, iooffset = 4; /* use the second dword for channels > 7 */ | 1196 | chan -= 8, iooffset = 4; /* |
1197 | * use the second dword | ||
1198 | * for channels > 7 | ||
1199 | */ | ||
1183 | 1200 | ||
1184 | if (aref != AREF_DIFF) { | 1201 | if (aref != AREF_DIFF) { |
1185 | aref = AREF_GROUND; | 1202 | aref = AREF_GROUND; |
1186 | command_byte |= 1 << 7; /* set bit 7 to indicate single-ended */ | 1203 | command_byte |= 1 << 7; /* |
1204 | * set bit 7 to indicate | ||
1205 | * single-ended | ||
1206 | */ | ||
1187 | } | 1207 | } |
1188 | if (range < 2) | 1208 | if (range < 2) |
1189 | adc_adjust = 0x8000; /* bipolar ranges (-5,5 .. -10,10 need to be adjusted -- that is.. they need to wrap around by adding 0x8000 */ | 1209 | adc_adjust = 0x8000; /* |
1210 | * bipolar ranges | ||
1211 | * (-5,5 .. -10,10 need to be | ||
1212 | * adjusted -- that is.. they | ||
1213 | * need to wrap around by | ||
1214 | * adding 0x8000 | ||
1215 | */ | ||
1190 | 1216 | ||
1191 | if (chan % 2) { | 1217 | if (chan % 2) { |
1192 | command_byte |= 1 << 6; /* odd-numbered channels have bit 6 set */ | 1218 | command_byte |= 1 << 6; /* |
1219 | * odd-numbered channels | ||
1220 | * have bit 6 set | ||
1221 | */ | ||
1193 | } | 1222 | } |
1194 | 1223 | ||
1195 | /* select the channel, bits 4-5 == chan/2 */ | 1224 | /* select the channel, bits 4-5 == chan/2 */ |
@@ -1199,16 +1228,22 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, | |||
1199 | command_byte |= (range & 0x3) << 2; | 1228 | command_byte |= (range & 0x3) << 2; |
1200 | 1229 | ||
1201 | /* need to do this twice to make sure mux settled */ | 1230 | /* need to do this twice to make sure mux settled */ |
1202 | outb(command_byte, iobase + iooffset + 2); /* chan/range/aref select */ | 1231 | /* chan/range/aref select */ |
1232 | outb(command_byte, iobase + iooffset + 2); | ||
1203 | 1233 | ||
1204 | adc_wait_ready(iobase + iooffset); /* wait for the adc to say it finised the conversion */ | 1234 | /* wait for the adc to say it finised the conversion */ |
1235 | adc_wait_ready(iobase + iooffset); | ||
1205 | 1236 | ||
1206 | outb(command_byte, iobase + iooffset + 2); /* select the chan/range/aref AGAIN */ | 1237 | /* select the chan/range/aref AGAIN */ |
1238 | outb(command_byte, iobase + iooffset + 2); | ||
1207 | 1239 | ||
1208 | adc_wait_ready(iobase + iooffset); | 1240 | adc_wait_ready(iobase + iooffset); |
1209 | 1241 | ||
1210 | sample = inb(iobase + iooffset + 0); /* read data lo byte */ | 1242 | /* read data lo byte */ |
1211 | sample |= inb(iobase + iooffset + 1) << 8; /* read data hi byte */ | 1243 | sample = inb(iobase + iooffset + 0); |
1244 | |||
1245 | /* read data hi byte */ | ||
1246 | sample |= inb(iobase + iooffset + 1) << 8; | ||
1212 | sample += adc_adjust; /* adjustment .. munge data */ | 1247 | sample += adc_adjust; /* adjustment .. munge data */ |
1213 | data[n] = sample; | 1248 | data[n] = sample; |
1214 | } | 1249 | } |
@@ -1270,15 +1305,24 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, | |||
1270 | 1305 | ||
1271 | wait_dac_ready(iobase + iooffset); | 1306 | wait_dac_ready(iobase + iooffset); |
1272 | 1307 | ||
1273 | outb(data[n] & 0xff, iobase + iooffset + 0); /* low order byte */ | 1308 | /* low order byte */ |
1274 | outb((data[n] >> 8) & 0xff, iobase + iooffset + 1); /* high order byte */ | 1309 | outb(data[n] & 0xff, iobase + iooffset + 0); |
1275 | command_byte = 0x70 | (chan << 1); /* set bit 4 of command byte to indicate data is loaded and trigger conversion */ | 1310 | |
1311 | /* high order byte */ | ||
1312 | outb((data[n] >> 8) & 0xff, iobase + iooffset + 1); | ||
1313 | |||
1314 | /* | ||
1315 | * set bit 4 of command byte to indicate | ||
1316 | * data is loaded and trigger conversion | ||
1317 | */ | ||
1318 | command_byte = 0x70 | (chan << 1); | ||
1276 | /* trigger converion */ | 1319 | /* trigger converion */ |
1277 | outb(command_byte, iobase + iooffset + 2); | 1320 | outb(command_byte, iobase + iooffset + 2); |
1278 | 1321 | ||
1279 | wait_dac_ready(iobase + iooffset); | 1322 | wait_dac_ready(iobase + iooffset); |
1280 | 1323 | ||
1281 | subpriv->ao.shadow_samples[chan] = data[n]; /* save to shadow register for ao_rinsn */ | 1324 | /* save to shadow register for ao_rinsn */ |
1325 | subpriv->ao.shadow_samples[chan] = data[n]; | ||
1282 | } | 1326 | } |
1283 | } | 1327 | } |
1284 | return n; | 1328 | return n; |