]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
block: Fix front merge check
[karo-tx-linux.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci1564.c
1 static int apci1564_timer_insn_config(struct comedi_device *dev,
2                                       struct comedi_subdevice *s,
3                                       struct comedi_insn *insn,
4                                       unsigned int *data)
5 {
6         struct apci1564_private *devpriv = dev->private;
7         unsigned int ctrl;
8
9         devpriv->tsk_current = current;
10
11         /* Stop the timer */
12         ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
13         ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
14                   ADDI_TCW_CTRL_ENA);
15         outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
16
17         if (data[1] == 1) {
18                 /* Enable timer int & disable all the other int sources */
19                 outl(ADDI_TCW_CTRL_IRQ_ENA,
20                      devpriv->timer + ADDI_TCW_CTRL_REG);
21                 outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG);
22                 outl(0x0, dev->iobase + APCI1564_DO_IRQ_REG);
23                 outl(0x0, dev->iobase + APCI1564_WDOG_IRQ_REG);
24                 if (devpriv->counters) {
25                         unsigned long iobase;
26
27                         iobase = devpriv->counters + ADDI_TCW_IRQ_REG;
28                         outl(0x0, iobase + APCI1564_COUNTER(0));
29                         outl(0x0, iobase + APCI1564_COUNTER(1));
30                         outl(0x0, iobase + APCI1564_COUNTER(2));
31                 }
32         } else {
33                 /* disable Timer interrupt */
34                 outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG);
35         }
36
37         /* Loading Timebase */
38         outl(data[2], devpriv->timer + ADDI_TCW_TIMEBASE_REG);
39
40         /* Loading the Reload value */
41         outl(data[3], devpriv->timer + ADDI_TCW_RELOAD_REG);
42
43         ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
44         ctrl &= ~(ADDI_TCW_CTRL_CNTR_ENA | ADDI_TCW_CTRL_MODE_MASK |
45                   ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
46                   ADDI_TCW_CTRL_TIMER_ENA | ADDI_TCW_CTRL_RESET_ENA |
47                   ADDI_TCW_CTRL_WARN_ENA | ADDI_TCW_CTRL_ENA);
48         ctrl |= ADDI_TCW_CTRL_MODE(2) | ADDI_TCW_CTRL_TIMER_ENA;
49         outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
50
51         return insn->n;
52 }
53
54 static int apci1564_timer_insn_write(struct comedi_device *dev,
55                                      struct comedi_subdevice *s,
56                                      struct comedi_insn *insn,
57                                      unsigned int *data)
58 {
59         struct apci1564_private *devpriv = dev->private;
60         unsigned int ctrl;
61
62         ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
63         ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG);
64         switch (data[1]) {
65         case 0: /* Stop The Timer */
66                 ctrl &= ~ADDI_TCW_CTRL_ENA;
67                 break;
68         case 1: /* Enable the Timer */
69                 ctrl |= ADDI_TCW_CTRL_ENA;
70                 break;
71         }
72         outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
73
74         return insn->n;
75 }
76
77 static int apci1564_timer_insn_read(struct comedi_device *dev,
78                                     struct comedi_subdevice *s,
79                                     struct comedi_insn *insn,
80                                     unsigned int *data)
81 {
82         struct apci1564_private *devpriv = dev->private;
83
84         /* Stores the status of the Timer */
85         data[0] = inl(devpriv->timer + ADDI_TCW_STATUS_REG) &
86                   ADDI_TCW_STATUS_OVERFLOW;
87
88         /* Stores the Actual value of the Timer */
89         data[1] = inl(devpriv->timer + ADDI_TCW_VAL_REG);
90
91         return insn->n;
92 }
93
94 static int apci1564_counter_insn_config(struct comedi_device *dev,
95                                         struct comedi_subdevice *s,
96                                         struct comedi_insn *insn,
97                                         unsigned int *data)
98 {
99         struct apci1564_private *devpriv = dev->private;
100         unsigned int chan = CR_CHAN(insn->chanspec);
101         unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
102         unsigned int ctrl;
103
104         devpriv->tsk_current = current;
105
106         /* Stop The Timer */
107         ctrl = inl(iobase + ADDI_TCW_CTRL_REG);
108         ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
109                   ADDI_TCW_CTRL_ENA);
110         outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
111
112         /* Set the reload value */
113         outl(data[3], iobase + ADDI_TCW_RELOAD_REG);
114
115         /* Set the mode */
116         ctrl &= ~(ADDI_TCW_CTRL_EXT_CLK_MASK | ADDI_TCW_CTRL_MODE_MASK |
117                   ADDI_TCW_CTRL_TIMER_ENA | ADDI_TCW_CTRL_RESET_ENA |
118                   ADDI_TCW_CTRL_WARN_ENA);
119         ctrl |= ADDI_TCW_CTRL_CNTR_ENA | ADDI_TCW_CTRL_MODE(data[4]);
120         outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
121
122         /* Enable or Disable Interrupt */
123         if (data[1])
124                 ctrl |= ADDI_TCW_CTRL_IRQ_ENA;
125         else
126                 ctrl &= ~ADDI_TCW_CTRL_IRQ_ENA;
127         outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
128
129         /* Set the Up/Down selection */
130         if (data[6])
131                 ctrl |= ADDI_TCW_CTRL_CNT_UP;
132         else
133                 ctrl &= ~ADDI_TCW_CTRL_CNT_UP;
134         outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
135
136         return insn->n;
137 }
138
139 static int apci1564_counter_insn_write(struct comedi_device *dev,
140                                        struct comedi_subdevice *s,
141                                        struct comedi_insn *insn,
142                                        unsigned int *data)
143 {
144         struct apci1564_private *devpriv = dev->private;
145         unsigned int chan = CR_CHAN(insn->chanspec);
146         unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
147         unsigned int ctrl;
148
149         ctrl = inl(iobase + ADDI_TCW_CTRL_REG);
150         ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG);
151         switch (data[1]) {
152         case 0: /* Stops the Counter subdevice */
153                 ctrl = 0;
154                 break;
155         case 1: /* Start the Counter subdevice */
156                 ctrl |= ADDI_TCW_CTRL_ENA;
157                 break;
158         case 2: /* Clears the Counter subdevice */
159                 ctrl |= ADDI_TCW_CTRL_GATE;
160                 break;
161         }
162         outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
163
164         return insn->n;
165 }
166
167 static int apci1564_counter_insn_read(struct comedi_device *dev,
168                                       struct comedi_subdevice *s,
169                                       struct comedi_insn *insn,
170                                       unsigned int *data)
171 {
172         struct apci1564_private *devpriv = dev->private;
173         unsigned int chan = CR_CHAN(insn->chanspec);
174         unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
175         unsigned int status;
176
177         /* Read the Counter Actual Value. */
178         data[0] = inl(iobase + ADDI_TCW_VAL_REG);
179
180         status = inl(iobase + ADDI_TCW_STATUS_REG);
181         data[1] = (status & ADDI_TCW_STATUS_SOFT_TRIG) ? 1 : 0;
182         data[2] = (status & ADDI_TCW_STATUS_HARDWARE_TRIG) ? 1 : 0;
183         data[3] = (status & ADDI_TCW_STATUS_SOFT_CLR) ? 1 : 0;
184         data[4] = (status & ADDI_TCW_STATUS_OVERFLOW) ? 1 : 0;
185
186         return insn->n;
187 }