1 /*
2  * 1394-Based Digital Camera Control Library
3  *
4  * Low-level register access functions
5  *
6  * Written by Damien Douxchamps <ddouxchamps@users.sf.net>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 
23 #include <inttypes.h>
24 #include "control.h"
25 #include "internal.h"
26 #include "offsets.h"
27 #include "register.h"
28 #include "utils.h"
29 #include "config.h"
30 
31 /* Note: debug modes can be very verbose. */
32 
33 /* To debug config rom structure: */
34 //#define DC1394_DEBUG_TAGGED_REGISTER_ACCESS
35 
36 #define FEATURE_TO_ABS_VALUE_OFFSET(feature, offset)                  \
37     {                                                                 \
38     if ( (feature > DC1394_FEATURE_MAX) || (feature < DC1394_FEATURE_MIN) )  \
39     {                                                                 \
40         return DC1394_FAILURE;                                        \
41     }                                                                 \
42     else if (feature < DC1394_FEATURE_ZOOM)                           \
43     {                                                                 \
44         offset= REG_CAMERA_FEATURE_ABS_HI_BASE;                       \
45         feature-= DC1394_FEATURE_MIN;                                 \
46     }                                                                 \
47     else                                                              \
48     {                                                                 \
49         offset= REG_CAMERA_FEATURE_ABS_LO_BASE;                       \
50         feature-= DC1394_FEATURE_ZOOM;                                \
51                                                                       \
52         if (feature >= DC1394_FEATURE_CAPTURE_SIZE)                   \
53         {                                                             \
54             feature+= 12;                                             \
55         }                                                             \
56                                                                       \
57     }                                                                 \
58                                                                       \
59     offset+= feature * 0x04U;                                         \
60     }
61 
62 
63 dc1394error_t
dc1394_get_registers(dc1394camera_t * camera,uint64_t offset,uint32_t * value,uint32_t num_regs)64 dc1394_get_registers (dc1394camera_t *camera, uint64_t offset,
65                       uint32_t *value, uint32_t num_regs)
66 {
67     dc1394camera_priv_t * cp = DC1394_CAMERA_PRIV (camera);
68 
69     if (camera == NULL)
70         return DC1394_CAMERA_NOT_INITIALIZED;
71 
72     return cp->platform->dispatch->camera_read (cp->pcam, offset, value,
73             num_regs);
74 }
75 
76 dc1394error_t
dc1394_set_registers(dc1394camera_t * camera,uint64_t offset,const uint32_t * value,uint32_t num_regs)77 dc1394_set_registers (dc1394camera_t *camera, uint64_t offset,
78                       const uint32_t *value, uint32_t num_regs)
79 {
80     dc1394camera_priv_t * cp = DC1394_CAMERA_PRIV (camera);
81 
82     if (camera == NULL)
83         return DC1394_CAMERA_NOT_INITIALIZED;
84 
85     return cp->platform->dispatch->camera_write (cp->pcam, offset, value,
86             num_regs);
87 }
88 
89 
90 /********************************************************************************/
91 /* Get/Set Command Registers                                                    */
92 /********************************************************************************/
93 dc1394error_t
dc1394_get_control_registers(dc1394camera_t * camera,uint64_t offset,uint32_t * value,uint32_t num_regs)94 dc1394_get_control_registers (dc1394camera_t *camera, uint64_t offset,
95                               uint32_t *value, uint32_t num_regs)
96 {
97     return dc1394_get_registers (camera,
98         camera->command_registers_base + offset, value, num_regs);
99 }
100 
101 dc1394error_t
dc1394_set_control_registers(dc1394camera_t * camera,uint64_t offset,const uint32_t * value,uint32_t num_regs)102 dc1394_set_control_registers (dc1394camera_t *camera, uint64_t offset,
103                               const uint32_t *value, uint32_t num_regs)
104 {
105     return dc1394_set_registers (camera,
106         camera->command_registers_base + offset, value, num_regs);
107 }
108 
109 /********************************************************************************/
110 /* Get/Set Advanced Features Registers                                          */
111 /********************************************************************************/
112 dc1394error_t
dc1394_get_adv_control_registers(dc1394camera_t * camera,uint64_t offset,uint32_t * value,uint32_t num_regs)113 dc1394_get_adv_control_registers (dc1394camera_t *camera, uint64_t offset,
114                                   uint32_t *value, uint32_t num_regs)
115 {
116     return dc1394_get_registers (camera,
117         camera->advanced_features_csr + offset, value, num_regs);
118 }
119 
120 dc1394error_t
dc1394_set_adv_control_registers(dc1394camera_t * camera,uint64_t offset,const uint32_t * value,uint32_t num_regs)121 dc1394_set_adv_control_registers (dc1394camera_t *camera, uint64_t offset,
122                                   const uint32_t *value, uint32_t num_regs)
123 {
124     return dc1394_set_registers (camera,
125         camera->advanced_features_csr + offset, value, num_regs);
126 }
127 
128 /********************************************************************************/
129 /* Get/Set Format_7 Registers                                                   */
130 /********************************************************************************/
131 
132 dc1394error_t
QueryFormat7CSROffset(dc1394camera_t * camera,dc1394video_mode_t mode,uint64_t * offset)133 QueryFormat7CSROffset(dc1394camera_t *camera, dc1394video_mode_t mode, uint64_t *offset)
134 {
135     int retval;
136     uint32_t temp;
137 
138     if (camera == NULL) {
139         return DC1394_CAMERA_NOT_INITIALIZED;
140     }
141 
142     if (!dc1394_is_video_mode_scalable(mode))
143         return DC1394_INVALID_VIDEO_FORMAT;
144 
145     retval=dc1394_get_control_register(camera, REG_CAMERA_V_CSR_INQ_BASE + ((mode - DC1394_VIDEO_MODE_FORMAT7_MIN) * 0x04U), &temp);
146     *offset=temp*4;
147     return retval;
148 }
149 
150 
151 dc1394error_t
dc1394_get_format7_register(dc1394camera_t * camera,unsigned int mode,uint64_t offset,uint32_t * value)152 dc1394_get_format7_register(dc1394camera_t *camera, unsigned int mode, uint64_t offset, uint32_t *value)
153 {
154     if (camera == NULL)
155         return DC1394_CAMERA_NOT_INITIALIZED;
156 
157     if (!dc1394_is_video_mode_scalable(mode))
158         return DC1394_INVALID_VIDEO_FORMAT;
159 
160     if (camera->format7_csr[mode-DC1394_VIDEO_MODE_FORMAT7_MIN]==0) {
161         if (QueryFormat7CSROffset(camera, mode,
162                     &camera->format7_csr[mode-DC1394_VIDEO_MODE_FORMAT7_MIN])
163                 != DC1394_SUCCESS) {
164             return DC1394_FAILURE;
165         }
166     }
167 
168     return dc1394_get_registers (camera,
169         camera->format7_csr[mode-DC1394_VIDEO_MODE_FORMAT7_MIN]+offset,
170         value, 1);
171 }
172 
173 
174 dc1394error_t
dc1394_set_format7_register(dc1394camera_t * camera,unsigned int mode,uint64_t offset,uint32_t value)175 dc1394_set_format7_register(dc1394camera_t *camera, unsigned int mode, uint64_t offset, uint32_t value)
176 {
177     if (camera == NULL)
178         return DC1394_CAMERA_NOT_INITIALIZED;
179 
180     if (!dc1394_is_video_mode_scalable(mode))
181         return DC1394_INVALID_VIDEO_FORMAT;;
182 
183     if (camera->format7_csr[mode-DC1394_VIDEO_MODE_FORMAT7_MIN]==0) {
184         QueryFormat7CSROffset(camera, mode,
185                 &camera->format7_csr[mode-DC1394_VIDEO_MODE_FORMAT7_MIN]);
186     }
187 
188     return dc1394_set_registers (camera,
189         camera->format7_csr[mode-DC1394_VIDEO_MODE_FORMAT7_MIN]+offset,
190         &value, 1);
191 }
192 
193 /********************************************************************************/
194 /* Get/Set Absolute Control Registers                                           */
195 /********************************************************************************/
196 
197 dc1394error_t
QueryAbsoluteCSROffset(dc1394camera_t * camera,dc1394feature_t feature,uint64_t * offset)198 QueryAbsoluteCSROffset(dc1394camera_t *camera, dc1394feature_t feature, uint64_t *offset)
199 {
200     int absoffset, retval;
201     uint32_t quadlet=0;
202 
203     if (camera == NULL)
204         return DC1394_CAMERA_NOT_INITIALIZED;
205 
206     FEATURE_TO_ABS_VALUE_OFFSET(feature, absoffset);
207     retval=dc1394_get_control_register(camera, absoffset, &quadlet);
208 
209     *offset=quadlet * 0x04;
210     return retval;
211 
212 }
213 
214 dc1394error_t
dc1394_get_absolute_register(dc1394camera_t * camera,unsigned int feature,uint64_t offset,uint32_t * value)215 dc1394_get_absolute_register(dc1394camera_t *camera, unsigned int feature,
216         uint64_t offset, uint32_t *value)
217 {
218     uint64_t absoffset;
219     if (camera == NULL)
220         return DC1394_CAMERA_NOT_INITIALIZED;
221 
222     QueryAbsoluteCSROffset(camera, feature, &absoffset);
223 
224     return dc1394_get_registers (camera, absoffset + offset, value, 1);
225 }
226 
227 dc1394error_t
dc1394_set_absolute_register(dc1394camera_t * camera,unsigned int feature,uint64_t offset,uint32_t value)228 dc1394_set_absolute_register(dc1394camera_t *camera, unsigned int feature,
229         uint64_t offset, uint32_t value)
230 {
231     uint64_t absoffset;
232     if (camera == NULL)
233         return DC1394_CAMERA_NOT_INITIALIZED;
234 
235     QueryAbsoluteCSROffset(camera, feature, &absoffset);
236 
237     return dc1394_set_registers (camera, absoffset + offset, &value, 1);
238 }
239 
240 /********************************************************************************/
241 /* Get/Set PIO Feature Registers                                                */
242 /********************************************************************************/
243 
244 dc1394error_t
dc1394_get_PIO_register(dc1394camera_t * camera,uint64_t offset,uint32_t * value)245 dc1394_get_PIO_register(dc1394camera_t *camera, uint64_t offset, uint32_t *value)
246 {
247     return dc1394_get_registers (camera, camera->PIO_control_csr + offset,
248             value, 1);
249 }
250 
251 dc1394error_t
dc1394_set_PIO_register(dc1394camera_t * camera,uint64_t offset,uint32_t value)252 dc1394_set_PIO_register(dc1394camera_t *camera, uint64_t offset, uint32_t value)
253 {
254     return dc1394_set_registers (camera, camera->PIO_control_csr + offset,
255             &value, 1);
256 }
257 
258 
259 /********************************************************************************/
260 /* Get/Set SIO Feature Registers                                                */
261 /********************************************************************************/
262 
263 dc1394error_t
dc1394_get_SIO_register(dc1394camera_t * camera,uint64_t offset,uint32_t * value)264 dc1394_get_SIO_register(dc1394camera_t *camera, uint64_t offset, uint32_t *value)
265 {
266     return dc1394_get_registers (camera, camera->SIO_control_csr + offset,
267             value, 1);
268 }
269 
270 dc1394error_t
dc1394_set_SIO_register(dc1394camera_t * camera,uint64_t offset,uint32_t value)271 dc1394_set_SIO_register(dc1394camera_t *camera, uint64_t offset, uint32_t value)
272 {
273     return dc1394_set_registers (camera, camera->SIO_control_csr + offset,
274             &value, 1);
275 }
276 
277 
278 /********************************************************************************/
279 /* Get/Set Strobe Feature Registers                                             */
280 /********************************************************************************/
281 dc1394error_t
dc1394_get_strobe_register(dc1394camera_t * camera,uint64_t offset,uint32_t * value)282 dc1394_get_strobe_register(dc1394camera_t *camera, uint64_t offset,
283         uint32_t *value)
284 {
285     return dc1394_get_registers (camera, camera->strobe_control_csr + offset,
286             value, 1);
287 }
288 
289 dc1394error_t
dc1394_set_strobe_register(dc1394camera_t * camera,uint64_t offset,uint32_t value)290 dc1394_set_strobe_register(dc1394camera_t *camera, uint64_t offset,
291         uint32_t value)
292 {
293     return dc1394_set_registers (camera, camera->strobe_control_csr + offset,
294             &value, 1);
295 }
296