xref: /illumos-gate/usr/src/uts/common/io/1394/targets/dcam1394/dcam_param.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * dcam_param.c
31  *
32  * dcam1394 driver.  Device parameter access.
33  */
34 
35 #include <sys/1394/targets/dcam1394/dcam.h>
36 #include <sys/1394/targets/dcam1394/dcam_param.h>
37 #include <sys/1394/targets/dcam1394/dcam_reg.h>
38 #include <sys/tnf_probe.h>
39 
40 /* index by vid_mode */
41 int g_frame_num_bytes[] = {
42 	57600,  /* vid mode 0 */
43 	153600, /* vid mode 1 */
44 	460800, /* vid mode 2 */
45 	614400, /* vid mode 3 */
46 	921600, /* vid mode 4 */
47 	307200  /* vid mode 5 */
48 };
49 
50 
51 static uint_t feature_csr_val_construct(uint_t subparam, uint_t param_val,
52     uint_t init_val);
53 static uint_t feature_csr_val_subparam_extract(uint_t subparam,
54     uint_t feature_csr_val);
55 static uint_t feature_elm_inq_reg_val_subparam_extract(uint_t subparam,
56     uint_t reg_val);
57 
58 
59 /*
60  * param_attr_init
61  */
62 int
63 param_attr_init(dcam_state_t *softc_p, dcam1394_param_attr_t param_attr)
64 {
65 	int	err, ret_err;
66 	uint_t	attr_bmap, cap_on_off, cap_power_ctrl, cap_read;
67 	uint_t	param, presence, subparam;
68 
69 	bzero(param_attr, sizeof (dcam1394_param_attr_t));
70 
71 	ret_err = DDI_SUCCESS;
72 
73 	/*
74 	 * power ctrl cap
75 	 */
76 	param = DCAM1394_PARAM_CAP_POWER_CTRL;
77 	subparam = DCAM1394_SUBPARAM_NONE;
78 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
79 	param_attr_set(param_attr, param, subparam, attr_bmap);
80 
81 	/*
82 	 * video mode cap
83 	 */
84 	param = DCAM1394_PARAM_CAP_VID_MODE;
85 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
86 
87 	for (subparam = DCAM1394_SUBPARAM_VID_MODE_0;
88 	    subparam <= DCAM1394_SUBPARAM_VID_MODE_5; subparam++) {
89 		param_attr_set(param_attr, param, subparam, attr_bmap);
90 	}
91 
92 	/*
93 	 * frame rate cap
94 	 */
95 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
96 
97 	for (param = DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_0;
98 	    param <= DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_5; param++) {
99 
100 		for (subparam = DCAM1394_SUBPARAM_FRAME_RATE_0;
101 		    subparam <= DCAM1394_SUBPARAM_FRAME_RATE_4; subparam++) {
102 			param_attr_set(param_attr, param, subparam, attr_bmap);
103 		}
104 	}
105 
106 	/*
107 	 * power
108 	 */
109 	param = DCAM1394_PARAM_POWER;
110 	subparam = DCAM1394_SUBPARAM_NONE;
111 	err = dcam1394_param_get(softc_p, DCAM1394_PARAM_CAP_POWER_CTRL,
112 	    DCAM1394_SUBPARAM_NONE, &cap_power_ctrl);
113 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
114 
115 	if (cap_power_ctrl) {
116 		attr_bmap |= CAP_SET;
117 	}
118 	param_attr_set(param_attr, param, subparam, attr_bmap);
119 
120 	/*
121 	 * video mode
122 	 */
123 	param = DCAM1394_PARAM_VID_MODE;
124 	subparam = DCAM1394_SUBPARAM_NONE;
125 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET | CAP_SET;
126 	param_attr_set(param_attr, param, subparam, attr_bmap);
127 
128 	/*
129 	 * frame rate
130 	 */
131 	param = DCAM1394_PARAM_FRAME_RATE;
132 	subparam = DCAM1394_SUBPARAM_NONE;
133 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET | CAP_SET;
134 	param_attr_set(param_attr, param, subparam, attr_bmap);
135 
136 	/*
137 	 * ring buffer capacity
138 	 */
139 	param = DCAM1394_PARAM_RING_BUFF_CAPACITY;
140 	subparam = DCAM1394_SUBPARAM_NONE;
141 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET | CAP_SET;
142 	param_attr_set(param_attr, param, subparam, attr_bmap);
143 
144 	/*
145 	 * ring buffer: num frames ready
146 	 */
147 	param = DCAM1394_PARAM_RING_BUFF_NUM_FRAMES_READY;
148 	subparam = DCAM1394_SUBPARAM_NONE;
149 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
150 	param_attr_set(param_attr, param, subparam, attr_bmap);
151 
152 	/*
153 	 * ring buffer: read ptr increment stride
154 	 */
155 	param = DCAM1394_PARAM_RING_BUFF_READ_PTR_INCR;
156 	subparam = DCAM1394_SUBPARAM_NONE;
157 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET | CAP_SET;
158 	param_attr_set(param_attr, param, subparam, attr_bmap);
159 
160 	/*
161 	 * frame size
162 	 */
163 	param = DCAM1394_PARAM_FRAME_NUM_BYTES;
164 	subparam = DCAM1394_SUBPARAM_NONE;
165 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
166 	param_attr_set(param_attr, param, subparam, attr_bmap);
167 
168 	/*
169 	 * cam status
170 	 */
171 	param = DCAM1394_PARAM_STATUS;
172 	subparam = DCAM1394_SUBPARAM_NONE;
173 	attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
174 	param_attr_set(param_attr, param, subparam, attr_bmap);
175 
176 	/*
177 	 * features
178 	 */
179 	for (param = DCAM1394_PARAM_BRIGHTNESS; param <= DCAM1394_PARAM_TILT;
180 	    param++) {
181 
182 		/*
183 		 * get feature presence
184 		 * If the operation to read the parameter fails, then act as
185 		 * though the feature is not implemented (because it isn't),
186 		 * don't report a DDI failure (as was previously done).
187 		 */
188 		err = dcam1394_param_get(softc_p, param,
189 		    DCAM1394_SUBPARAM_PRESENCE, &presence);
190 
191 		if (!err) {
192 			/* feature presence */
193 			subparam  = DCAM1394_SUBPARAM_PRESENCE;
194 			attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
195 			param_attr_set(param_attr, param, subparam, attr_bmap);
196 
197 			if (presence) {
198 				/* feature cap read */
199 				subparam  = DCAM1394_SUBPARAM_CAP_READ;
200 				attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
201 				param_attr_set(param_attr, param,
202 				    subparam, attr_bmap);
203 
204 				/* feature cap on/off */
205 				subparam  = DCAM1394_SUBPARAM_CAP_ON_OFF;
206 				attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
207 				param_attr_set(param_attr, param,
208 				    subparam, attr_bmap);
209 
210 				/* feature cap ctrl auto */
211 				subparam  = DCAM1394_SUBPARAM_CAP_CTRL_AUTO;
212 				attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
213 				param_attr_set(param_attr, param,
214 				    subparam, attr_bmap);
215 
216 				/* feature cap ctrl manual */
217 				subparam  = DCAM1394_SUBPARAM_CAP_CTRL_MANUAL;
218 				attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
219 				param_attr_set(param_attr, param,
220 				    subparam, attr_bmap);
221 
222 				/* feature min val */
223 				subparam  = DCAM1394_SUBPARAM_MIN_VAL;
224 				attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
225 				param_attr_set(param_attr, param,
226 				    subparam, attr_bmap);
227 
228 				/* feature max val */
229 				subparam  = DCAM1394_SUBPARAM_MAX_VAL;
230 				attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
231 				param_attr_set(param_attr, param,
232 				    subparam, attr_bmap);
233 
234 				/* feature on/off */
235 				subparam = DCAM1394_SUBPARAM_ON_OFF;
236 
237 				err = dcam1394_param_get(softc_p, param,
238 				    DCAM1394_SUBPARAM_CAP_ON_OFF, &cap_on_off);
239 
240 				attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
241 
242 				if (cap_on_off) {
243 					attr_bmap |= (CAP_SET | CAP_CTRL_SET);
244 				}
245 
246 				param_attr_set(param_attr, param,
247 				    subparam, attr_bmap);
248 
249 				/* feature control mode */
250 				subparam = DCAM1394_SUBPARAM_CTRL_MODE;
251 				attr_bmap = IS_VALID | IS_PRESENT | CAP_GET |
252 				    CAP_SET | CAP_CTRL_SET;
253 
254 				param_attr_set(param_attr, param,
255 				    subparam, attr_bmap);
256 
257 				/* get value read-out capability */
258 				err  = dcam1394_param_get(softc_p, param,
259 				    DCAM1394_SUBPARAM_CAP_READ,
260 				    &cap_read);
261 
262 				if (param == DCAM1394_PARAM_WHITE_BALANCE) {
263 					/*
264 					 * white balance feature: u, v value
265 					 */
266 					subparam = DCAM1394_SUBPARAM_U_VALUE;
267 					attr_bmap = IS_VALID | IS_PRESENT |
268 					    CAP_SET | CAP_CTRL_SET;
269 
270 					if (cap_read) {
271 						attr_bmap |= CAP_GET;
272 					}
273 
274 					param_attr_set(param_attr, param,
275 					    subparam, attr_bmap);
276 
277 					subparam = DCAM1394_SUBPARAM_V_VALUE;
278 					attr_bmap = IS_VALID | IS_PRESENT |
279 					    CAP_SET | CAP_CTRL_SET;
280 
281 					if (cap_read) {
282 						attr_bmap |= CAP_GET;
283 					}
284 
285 					param_attr_set(param_attr, param,
286 					    subparam, attr_bmap);
287 
288 				} else {
289 					/* feature value */
290 					subparam = DCAM1394_SUBPARAM_VALUE;
291 					attr_bmap = IS_VALID | IS_PRESENT |
292 					    CAP_SET | CAP_CTRL_SET;
293 
294 					if (cap_read) {
295 						attr_bmap |= CAP_GET;
296 					}
297 
298 					param_attr_set(param_attr, param,
299 					    subparam, attr_bmap);
300 				}
301 
302 			}
303 
304 		}
305 	}
306 
307 	return (ret_err);
308 }
309 
310 
311 /*
312  * param_attr_set
313  */
314 void
315 param_attr_set(dcam1394_param_attr_t  param_attr, uint_t param,
316     uint_t subparam, uint_t attr_bmap)
317 {
318 	param_attr[param][subparam] = attr_bmap;
319 }
320 
321 
322 /*
323  * dcam1394_ioctl_param_get
324  *
325  * softc's param_attr field must be initialized via param_attr_init()
326  * before using this function.
327  */
328 int
329 dcam1394_ioctl_param_get(dcam_state_t *softc_p,
330     dcam1394_param_list_t param_list)
331 {
332 	int err, ret_err;
333 	int param, subparam;
334 	uint_t cap_get, is_present, is_valid, val;
335 
336 	ret_err = 0;
337 
338 	for (param = 0; param < DCAM1394_NUM_PARAM; param++) {
339 		for (subparam = 0;
340 		    subparam < DCAM1394_NUM_SUBPARAM;
341 		    subparam++) {
342 
343 			if (param_list[param][subparam].flag) {
344 				is_valid =
345 				    softc_p->param_attr[param][subparam] &
346 				    IS_VALID;
347 				is_present =
348 				    softc_p->param_attr[param][subparam] &
349 				    IS_PRESENT;
350 				cap_get =
351 				    softc_p->param_attr[param][subparam] &
352 				    CAP_GET;
353 
354 				if (is_valid && is_present && cap_get) {
355 					if (err = dcam1394_param_get(softc_p,
356 					    param, subparam, &val)) {
357 
358 					    param_list[param][subparam].err = 1;
359 					    ret_err = 1;
360 					}
361 
362 					if (!err) {
363 					    param_list[param][subparam].val =
364 						val;
365 					}
366 				} else {
367 					param_list[param][subparam].err = 1;
368 					ret_err = 1;
369 				}
370 			}
371 		}
372 	}
373 
374 	return (ret_err);
375 }
376 
377 
378 /*
379  * dcam1394_ioctl_param_set
380  * softc's param_attr field must be initialized via param_attr_init()
381  * before using this function.
382  */
383 int
384 dcam1394_ioctl_param_set(dcam_state_t *softc_p, int is_ctrl_file,
385     dcam1394_param_list_t param_list)
386 {
387 	int param, subparam;
388 	int ret_err;
389 	uint_t cap_set, is_present, is_valid, val;
390 
391 	ret_err = 0;
392 
393 	for (param = 0; param < DCAM1394_NUM_PARAM; param++) {
394 		for (subparam = 0;
395 		    subparam < DCAM1394_NUM_SUBPARAM;
396 		    subparam++) {
397 			if (param_list[param][subparam].flag) {
398 				is_valid =
399 				    softc_p->param_attr[param][subparam] &
400 				    IS_VALID;
401 				is_present =
402 				    softc_p->param_attr[param][subparam] &
403 				    IS_PRESENT;
404 
405 				cap_set = is_ctrl_file ?
406 				    (softc_p->param_attr[param][subparam]
407 				    & CAP_CTRL_SET) :
408 				    (softc_p->param_attr[param][subparam]
409 				    & CAP_SET);
410 
411 				if (is_valid && is_present && cap_set) {
412 					val = param_list[param][subparam].val;
413 
414 					if (dcam1394_param_set(softc_p,
415 					    param, subparam, val)) {
416 
417 					    param_list[param][subparam].err = 1;
418 					    ret_err = 1;
419 					}
420 				} else {
421 					param_list[param][subparam].err = 1;
422 					ret_err = 1;
423 				}
424 			}
425 		}
426 	}
427 
428 	return (ret_err);
429 }
430 
431 
432 /*
433  * dcam1394_param_get
434  */
435 int
436 dcam1394_param_get(dcam_state_t  *softc_p, uint_t param, uint_t subparam,
437     uint_t *val_p)
438 {
439 	int err;
440 
441 	switch (param) {
442 
443 	case DCAM1394_PARAM_CAP_POWER_CTRL:
444 		err = param_cap_power_ctrl_get(softc_p, val_p);
445 		break;
446 
447 	case DCAM1394_PARAM_CAP_VID_MODE:
448 		err = param_cap_vid_mode_get(softc_p, subparam, val_p);
449 		break;
450 
451 	case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_0:
452 	case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_1:
453 	case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_2:
454 	case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_3:
455 	case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_4:
456 	case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_5:
457 		err = param_cap_frame_rate_get(softc_p, param, subparam, val_p);
458 		break;
459 
460 	case DCAM1394_PARAM_POWER:
461 		err = param_power_get(softc_p, val_p);
462 		break;
463 
464 	case DCAM1394_PARAM_VID_MODE:
465 		err = param_vid_mode_get(softc_p, val_p);
466 		break;
467 
468 	case DCAM1394_PARAM_FRAME_RATE:
469 		err = param_frame_rate_get(softc_p, val_p);
470 		break;
471 
472 	case DCAM1394_PARAM_RING_BUFF_CAPACITY:
473 		err = param_ring_buff_capacity_get(softc_p, val_p);
474 		break;
475 
476 	case DCAM1394_PARAM_RING_BUFF_NUM_FRAMES_READY:
477 		err = param_ring_buff_num_frames_ready_get(softc_p, val_p);
478 		break;
479 
480 	case DCAM1394_PARAM_RING_BUFF_READ_PTR_INCR:
481 		err = param_ring_buff_read_ptr_incr_get(softc_p, val_p);
482 		break;
483 
484 	case DCAM1394_PARAM_FRAME_NUM_BYTES:
485 		err = param_frame_num_bytes_get(softc_p, val_p);
486 		break;
487 
488 	case DCAM1394_PARAM_STATUS:
489 		err = param_status_get(softc_p, val_p);
490 		break;
491 
492 	case DCAM1394_PARAM_BRIGHTNESS:
493 		err = param_brightness_get(softc_p, subparam, val_p);
494 		break;
495 
496 	case DCAM1394_PARAM_EXPOSURE:
497 		err = param_exposure_get(softc_p, subparam, val_p);
498 		break;
499 
500 	case DCAM1394_PARAM_SHARPNESS:
501 		err = param_sharpness_get(softc_p, subparam, val_p);
502 		break;
503 
504 	case DCAM1394_PARAM_WHITE_BALANCE:
505 		err = param_white_balance_get(softc_p, subparam, val_p);
506 		break;
507 
508 	case DCAM1394_PARAM_HUE:
509 		err = param_hue_get(softc_p, subparam, val_p);
510 		break;
511 
512 	case DCAM1394_PARAM_SATURATION:
513 		err = param_saturation_get(softc_p, subparam, val_p);
514 		break;
515 
516 	case DCAM1394_PARAM_GAMMA:
517 		err = param_gamma_get(softc_p, subparam, val_p);
518 		break;
519 
520 	case DCAM1394_PARAM_SHUTTER:
521 		err = param_shutter_get(softc_p, subparam, val_p);
522 		break;
523 
524 	case DCAM1394_PARAM_GAIN:
525 		err = param_gain_get(softc_p, subparam, val_p);
526 		break;
527 
528 	case DCAM1394_PARAM_IRIS:
529 		err = param_iris_get(softc_p, subparam, val_p);
530 		break;
531 
532 	case DCAM1394_PARAM_FOCUS:
533 		err = param_focus_get(softc_p, subparam, val_p);
534 		break;
535 
536 	case DCAM1394_PARAM_ZOOM:
537 		err = param_zoom_get(softc_p, subparam, val_p);
538 		break;
539 
540 	case DCAM1394_PARAM_PAN:
541 		err = param_pan_get(softc_p, subparam, val_p);
542 		break;
543 
544 	case DCAM1394_PARAM_TILT:
545 		err = param_tilt_get(softc_p, subparam, val_p);
546 		break;
547 
548 	default:
549 		err = 1;
550 		break;
551 	}
552 
553 	return (err);
554 }
555 
556 
557 /*
558  * dcam1394_param_set
559  */
560 int
561 dcam1394_param_set(dcam_state_t *softc_p, uint_t param, uint_t subparam,
562     uint_t val)
563 {
564 	int err;
565 
566 	switch (param) {
567 
568 	case DCAM1394_PARAM_POWER:
569 		err = param_power_set(softc_p, val);
570 		break;
571 
572 	case DCAM1394_PARAM_VID_MODE:
573 		err = param_vid_mode_set(softc_p, val);
574 		break;
575 
576 	case DCAM1394_PARAM_FRAME_RATE:
577 		err = param_frame_rate_set(softc_p, val);
578 		break;
579 
580 	case DCAM1394_PARAM_RING_BUFF_CAPACITY:
581 		err = param_ring_buff_capacity_set(softc_p, val);
582 		break;
583 
584 	case DCAM1394_PARAM_RING_BUFF_READ_PTR_INCR:
585 		err = param_ring_buff_read_ptr_incr_set(softc_p, val);
586 		break;
587 
588 	case DCAM1394_PARAM_BRIGHTNESS:
589 		err = param_brightness_set(softc_p, subparam, val);
590 		break;
591 
592 	case DCAM1394_PARAM_EXPOSURE:
593 		err = param_exposure_set(softc_p, subparam, val);
594 		break;
595 
596 	case DCAM1394_PARAM_SHARPNESS:
597 		err = param_sharpness_set(softc_p, subparam, val);
598 		break;
599 
600 	case DCAM1394_PARAM_WHITE_BALANCE:
601 		err = param_white_balance_set(softc_p, subparam, val);
602 		break;
603 
604 	case DCAM1394_PARAM_HUE:
605 		err = param_hue_set(softc_p, subparam, val);
606 		break;
607 
608 	case DCAM1394_PARAM_SATURATION:
609 		err = param_saturation_set(softc_p, subparam, val);
610 		break;
611 
612 	case DCAM1394_PARAM_GAMMA:
613 		err = param_gamma_set(softc_p, subparam, val);
614 		break;
615 
616 	case DCAM1394_PARAM_SHUTTER:
617 		err = param_shutter_set(softc_p, subparam, val);
618 		break;
619 
620 	case DCAM1394_PARAM_GAIN:
621 		err = param_gain_set(softc_p, subparam, val);
622 		break;
623 
624 	case DCAM1394_PARAM_IRIS:
625 		err = param_iris_set(softc_p, subparam, val);
626 		break;
627 
628 	case DCAM1394_PARAM_FOCUS:
629 		err = param_focus_set(softc_p, subparam, val);
630 		break;
631 
632 	case DCAM1394_PARAM_ZOOM:
633 		err = param_zoom_set(softc_p, subparam, val);
634 		break;
635 
636 	case DCAM1394_PARAM_PAN:
637 		err = param_pan_set(softc_p, subparam, val);
638 		break;
639 
640 	case DCAM1394_PARAM_TILT:
641 		err = param_tilt_set(softc_p, subparam, val);
642 		break;
643 
644 	default:
645 		err = 1;
646 		break;
647 	}
648 
649 	return (err);
650 }
651 
652 
653 /*
654  * feature_get
655  */
656 int
657 feature_get(dcam_state_t *softc_p, uint_t feature_csr_offs,
658     uint_t feature_elm_inq_reg_offs, uint_t subparam, uint_t *val_p)
659 {
660 	dcam1394_reg_io_t	reg_io;
661 	uint_t			val;
662 
663 	switch (subparam) {
664 
665 	case DCAM1394_SUBPARAM_PRESENCE:
666 	case DCAM1394_SUBPARAM_ON_OFF:
667 	case DCAM1394_SUBPARAM_CTRL_MODE:
668 	case DCAM1394_SUBPARAM_VALUE:
669 	case DCAM1394_SUBPARAM_U_VALUE:
670 	case DCAM1394_SUBPARAM_V_VALUE:
671 		reg_io.offs = feature_csr_offs +
672 		    DCAM1394_REG_OFFS_FEATURE_CSR_BASE;
673 
674 		if (dcam_reg_read(softc_p, &reg_io)) {
675 			return (1);
676 		}
677 
678 		val = feature_csr_val_subparam_extract(subparam, reg_io.val);
679 		break;
680 
681 	case DCAM1394_SUBPARAM_CAP_READ:
682 	case DCAM1394_SUBPARAM_CAP_ON_OFF:
683 	case DCAM1394_SUBPARAM_CAP_CTRL_AUTO:
684 	case DCAM1394_SUBPARAM_CAP_CTRL_MANUAL:
685 	case DCAM1394_SUBPARAM_MIN_VAL:
686 	case DCAM1394_SUBPARAM_MAX_VAL:
687 		reg_io.offs = feature_elm_inq_reg_offs +
688 		    DCAM1394_REG_OFFS_FEATURE_ELM_INQ_BASE;
689 
690 		if (dcam_reg_read(softc_p, &reg_io)) {
691 			return (1);
692 		}
693 
694 		val = feature_elm_inq_reg_val_subparam_extract(subparam,
695 		    reg_io.val);
696 
697 		break;
698 
699 	default:
700 		return (1);
701 	}
702 
703 	*val_p = val;
704 
705 	return (0);
706 }
707 
708 
709 /*
710  * feature_set
711  */
712 int
713 feature_set(dcam_state_t *softc_p, uint_t feature_csr_offs,
714     uint_t subparam, uint_t val)
715 {
716 	dcam1394_reg_io_t  reg_io;
717 
718 	reg_io.offs = feature_csr_offs + DCAM1394_REG_OFFS_FEATURE_CSR_BASE;
719 
720 	if (dcam_reg_read(softc_p, &reg_io)) {
721 		return (1);
722 	}
723 
724 	reg_io.val = feature_csr_val_construct(subparam, val, reg_io.val);
725 
726 	if (dcam_reg_write(softc_p, &reg_io)) {
727 		return (1);
728 	}
729 
730 	return (0);
731 }
732 
733 
734 /*
735  * param_cap_power_ctrl_get
736  */
737 int
738 param_cap_power_ctrl_get(dcam_state_t *softc_p, uint_t *val_p)
739 {
740 	dcam1394_reg_io_t reg_io;
741 
742 	reg_io.offs = DCAM1394_REG_OFFS_BASIC_FUNC_INQ;
743 
744 	if (dcam_reg_read(softc_p, &reg_io)) {
745 		return (1);
746 	}
747 
748 	*val_p = (reg_io.val & DCAM1394_MASK_CAM_POWER_CTRL) >>
749 	    DCAM1394_SHIFT_CAM_POWER_CTRL;
750 
751 	return (0);
752 }
753 
754 
755 /*
756  * param_cap_vid_mode_get
757  * dcam spec: sec 1.2.1.1
758  */
759 int
760 param_cap_vid_mode_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
761 {
762 	dcam1394_reg_io_t	reg_io;
763 	uint_t			mask, shift, vid_mode;
764 
765 	vid_mode    = subparam - DCAM1394_SUBPARAM_VID_MODE_0;
766 	reg_io.offs = DCAM1394_REG_OFFS_VID_MODE_INQ;
767 
768 	if (dcam_reg_read(softc_p, &reg_io)) {
769 		return (1);
770 	}
771 
772 	mask  = 1 << (31 - vid_mode);
773 	shift = 31 - vid_mode;
774 
775 	*val_p = (reg_io.val & mask) >> shift;
776 
777 	return (0);
778 }
779 
780 
781 /*
782  * param_cap_frame_rate_get()
783  * dcam spec: sec 1.2.2
784  */
785 int
786 param_cap_frame_rate_get(dcam_state_t *softc_p, uint_t param,
787     uint_t subparam, uint_t *val_p)
788 {
789 	dcam1394_reg_io_t	reg_io;
790 	uint_t			frame_rate, mask, shift, vid_mode;
791 
792 	vid_mode   = param - DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_0;
793 	frame_rate = subparam - DCAM1394_SUBPARAM_FRAME_RATE_0;
794 
795 	reg_io.offs = DCAM1394_REG_OFFS_FRAME_RATE_INQ_BASE + (4 * vid_mode);
796 
797 	if (dcam_reg_read(softc_p, &reg_io)) {
798 		return (1);
799 	}
800 
801 	mask = 1 << (31 - (frame_rate + 1));
802 	shift = 31 - (frame_rate + 1);
803 
804 	*val_p = (reg_io.val & mask) >> shift;
805 
806 	return (0);
807 }
808 
809 
810 /*
811  * param_power_get
812  */
813 int
814 param_power_get(dcam_state_t *softc_p, uint_t *val_p)
815 {
816 	dcam1394_reg_io_t reg_io;
817 
818 	reg_io.offs = DCAM1394_REG_OFFS_CAMERA_POWER;
819 
820 	if (dcam_reg_read(softc_p, &reg_io)) {
821 		return (1);
822 	}
823 
824 	*val_p = reg_io.val >> DCAM1394_SHIFT_CAMERA_POWER;
825 
826 	return (0);
827 }
828 
829 
830 /*
831  * param_power_set()
832  */
833 int
834 param_power_set(dcam_state_t *softc_p, uint_t val)
835 {
836 	dcam1394_reg_io_t reg_io;
837 
838 	reg_io.offs = DCAM1394_REG_OFFS_CAMERA_POWER;
839 	reg_io.val = val << DCAM1394_SHIFT_CAMERA_POWER;
840 
841 	if (dcam_reg_write(softc_p, &reg_io)) {
842 		return (1);
843 	}
844 
845 	return (0);
846 }
847 
848 
849 /*
850  * param_vid_mode_get
851  */
852 int
853 param_vid_mode_get(dcam_state_t *softc_p, uint_t *val_p)
854 {
855 	dcam1394_reg_io_t  reg_io;
856 
857 	reg_io.offs = DCAM1394_REG_OFFS_CUR_V_MODE;
858 
859 	if (dcam_reg_read(softc_p, &reg_io)) {
860 		return (1);
861 	}
862 
863 	*val_p = reg_io.val >> DCAM1394_SHIFT_CUR_V_MODE;
864 
865 	return (0);
866 }
867 
868 
869 /*
870  * param_vid_mode_set
871  */
872 int
873 param_vid_mode_set(dcam_state_t *softc_p, uint_t val)
874 {
875 	dcam1394_reg_io_t	reg_io;
876 	uint_t			vid_mode;
877 
878 	vid_mode = val - DCAM1394_VID_MODE_0;
879 
880 	reg_io.offs = DCAM1394_REG_OFFS_CUR_V_MODE;
881 	reg_io.val  = vid_mode << DCAM1394_SHIFT_CUR_V_MODE;
882 
883 	if (dcam_reg_write(softc_p, &reg_io)) {
884 		return (1);
885 	}
886 
887 	softc_p->cur_vid_mode = val;
888 
889 	/*
890 	 * if we are currently receiving frames, we need to do a restart
891 	 * so that the new vid mode value takes effect
892 	 */
893 	if (softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT) {
894 		(void) dcam_frame_rcv_stop(softc_p);
895 		(void) dcam1394_ioctl_frame_rcv_start(softc_p);
896 	}
897 
898 	return (0);
899 }
900 
901 
902 /*
903  * param_frame_rate_get
904  */
905 int
906 param_frame_rate_get(dcam_state_t *softc_p, uint_t *val_p)
907 {
908 	dcam1394_reg_io_t	reg_io;
909 	uint_t			frame_rate;
910 
911 	reg_io.offs = DCAM1394_REG_OFFS_CUR_V_FRM_RATE;
912 
913 	if (dcam_reg_read(softc_p, &reg_io)) {
914 		return (1);
915 	}
916 
917 	frame_rate = reg_io.val >> DCAM1394_SHIFT_CUR_V_FRM_RATE;
918 
919 	*val_p = frame_rate - 1 + DCAM1394_FRAME_RATE_0;
920 
921 	return (0);
922 }
923 
924 
925 /*
926  * param_frame_rate_set
927  */
928 int
929 param_frame_rate_set(dcam_state_t *softc_p, uint_t val)
930 {
931 	dcam1394_reg_io_t	reg_io;
932 	uint_t			frame_rate;
933 
934 	/* if we are currently receiving frames, stop the camera */
935 	if (softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT) {
936 		(void) dcam_frame_rcv_stop(softc_p);
937 
938 		frame_rate = val - DCAM1394_FRAME_RATE_0 + 1;
939 
940 		reg_io.offs = DCAM1394_REG_OFFS_CUR_V_FRM_RATE;
941 		reg_io.val  = frame_rate << DCAM1394_SHIFT_CUR_V_FRM_RATE;
942 
943 		if (dcam_reg_write(softc_p, &reg_io)) {
944 			return (1);
945 		}
946 
947 		/*
948 		 * Update the state info.
949 		 * note: the driver maintains frame rate in an array
950 		 * whereas the the camera uses predefined values whose
951 		 * lowest frame rate starts at 6
952 		 */
953 		softc_p->cur_frame_rate = val - 6;
954 
955 		/* restart the camera */
956 		(void) dcam1394_ioctl_frame_rcv_start(softc_p);
957 	} else {
958 		frame_rate = val - DCAM1394_FRAME_RATE_0 + 1;
959 
960 		reg_io.offs = DCAM1394_REG_OFFS_CUR_V_FRM_RATE;
961 		reg_io.val  = frame_rate << DCAM1394_SHIFT_CUR_V_FRM_RATE;
962 
963 		if (dcam_reg_write(softc_p, &reg_io)) {
964 			return (1);
965 		}
966 
967 		/* see note above re skewing of value by 6 */
968 		softc_p->cur_frame_rate = val - 6;
969 	}
970 
971 	return (0);
972 }
973 
974 
975 /*
976  * param_ring_buff_capacity_get()
977  */
978 int
979 param_ring_buff_capacity_get(dcam_state_t *softc_p, uint_t *val_p)
980 {
981 	*val_p = softc_p->cur_ring_buff_capacity;
982 
983 	return (0);
984 }
985 
986 
987 /*
988  * param_ring_buff_capacity_set
989  */
990 int
991 param_ring_buff_capacity_set(dcam_state_t *softc_p, uint_t val)
992 {
993 	/* bounds check */
994 	if ((val < 2) || (val > 30)) {
995 		return (1);
996 	}
997 
998 	/* update our state info */
999 	softc_p->cur_ring_buff_capacity = val;
1000 
1001 
1002 	/*
1003 	 * if we are currently receiving frames, we need to do a restart
1004 	 * so that the new buff_capacity value takes effect
1005 	 */
1006 	if (softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT) {
1007 		(void) dcam_frame_rcv_stop(softc_p);
1008 		(void) dcam1394_ioctl_frame_rcv_start(softc_p);
1009 	}
1010 	return (0);
1011 }
1012 
1013 
1014 /*
1015  * param_ring_buff_num_frames_ready_get()
1016  */
1017 int
1018 param_ring_buff_num_frames_ready_get(dcam_state_t *softc_p, uint_t *val_p)
1019 {
1020 	size_t read_pos, write_pos;
1021 
1022 	/*
1023 	 * note: currently we support only one read_ptr_id, so the
1024 	 * following logic will work. If multiple read_ptr_id's are
1025 	 * supported, this function call will need to receive a
1026 	 * read_ptr_id
1027 	 */
1028 
1029 	if (softc_p->ring_buff_p == NULL) {
1030 		return (1);
1031 	}
1032 
1033 	mutex_enter(&softc_p->dcam_frame_is_done_mutex);
1034 
1035 	read_pos  = ring_buff_read_ptr_pos_get(softc_p->ring_buff_p, 0);
1036 	write_pos = ring_buff_write_ptr_pos_get(softc_p->ring_buff_p);
1037 
1038 	if (read_pos < write_pos) {
1039 		*val_p = write_pos - read_pos;
1040 	} else {
1041 		*val_p = (softc_p->ring_buff_p->num_buffs + write_pos) -
1042 		    read_pos;
1043 	}
1044 
1045 	mutex_exit(&softc_p->dcam_frame_is_done_mutex);
1046 
1047 	return (0);
1048 }
1049 
1050 
1051 /*
1052  * param_ring_buff_read_ptr_incr_get()
1053  */
1054 
1055 int
1056 param_ring_buff_read_ptr_incr_get(dcam_state_t *softc_p, uint_t *val_p)
1057 {
1058 	if (softc_p->ring_buff_p == NULL) {
1059 		return (1);
1060 	}
1061 
1062 	*val_p = softc_p->ring_buff_p->read_ptr_incr_val;
1063 
1064 	return (0);
1065 }
1066 
1067 
1068 /*
1069  * param_ring_buff_read_ptr_incr_set
1070  */
1071 int
1072 param_ring_buff_read_ptr_incr_set(dcam_state_t *softc_p, uint_t val)
1073 {
1074 	if (softc_p->ring_buff_p == NULL) {
1075 		return (1);
1076 	}
1077 
1078 	softc_p->ring_buff_p->read_ptr_incr_val = val;
1079 
1080 	return (0);
1081 }
1082 
1083 
1084 /*
1085  * param_frame_num_bytes_get
1086  */
1087 int
1088 param_frame_num_bytes_get(dcam_state_t *softc_p, uint_t *val_p)
1089 {
1090 	if (softc_p == NULL) {
1091 		return (1);
1092 	}
1093 
1094 	*val_p = g_frame_num_bytes[softc_p->cur_vid_mode];
1095 
1096 	return (0);
1097 }
1098 
1099 
1100 /*
1101  * param_status_get()
1102  */
1103 
1104 int
1105 param_status_get(dcam_state_t *softc_p, uint_t *val_p)
1106 {
1107 	mutex_enter(&softc_p->dcam_frame_is_done_mutex);
1108 
1109 	*val_p = softc_p->param_status;
1110 	softc_p->param_status = 0;
1111 
1112 	mutex_exit(&softc_p->dcam_frame_is_done_mutex);
1113 
1114 	return (0);
1115 }
1116 
1117 
1118 /*
1119  * param_brightness_get
1120  */
1121 int
1122 param_brightness_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1123 {
1124 	int	ret_val;
1125 	uint_t	feature_csr_offs;
1126 	uint_t	feature_elm_inq_reg_offs;
1127 
1128 	feature_csr_offs = DCAM1394_REG_OFFS_BRIGHTNESS_CSR;
1129 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_BRIGHTNESS_INQ;
1130 
1131 	ret_val = feature_get(softc_p, feature_csr_offs,
1132 	    feature_elm_inq_reg_offs, subparam, val_p);
1133 
1134 	return (ret_val);
1135 }
1136 
1137 
1138 /*
1139  * param_brightness_set()
1140  */
1141 int
1142 param_brightness_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1143 {
1144 	int	ret_val;
1145 	uint_t feature_csr_offs;
1146 
1147 	feature_csr_offs = DCAM1394_REG_OFFS_BRIGHTNESS_CSR;
1148 
1149 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1150 
1151 	return (ret_val);
1152 }
1153 
1154 
1155 /*
1156  * param_exposure_get
1157  */
1158 int
1159 param_exposure_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1160 {
1161 	int	ret_val;
1162 	uint_t	feature_csr_offs;
1163 	uint_t	feature_elm_inq_reg_offs;
1164 
1165 	feature_csr_offs = DCAM1394_REG_OFFS_EXPOSURE_CSR;
1166 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_EXPOSURE_INQ;
1167 
1168 	ret_val = feature_get(softc_p, feature_csr_offs,
1169 	    feature_elm_inq_reg_offs, subparam, val_p);
1170 
1171 	return (ret_val);
1172 }
1173 
1174 
1175 /*
1176  * param_exposure_set
1177  */
1178 int
1179 param_exposure_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1180 {
1181 	int	ret_val;
1182 	uint_t	feature_csr_offs;
1183 
1184 	feature_csr_offs = DCAM1394_REG_OFFS_EXPOSURE_CSR;
1185 
1186 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1187 
1188 	return (ret_val);
1189 }
1190 
1191 
1192 /*
1193  * param_sharpness_get
1194  */
1195 int
1196 param_sharpness_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1197 {
1198 	int	ret_val;
1199 	uint_t	feature_csr_offs;
1200 	uint_t	feature_elm_inq_reg_offs;
1201 
1202 	feature_csr_offs = DCAM1394_REG_OFFS_SHARPNESS_CSR;
1203 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_SHARPNESS_INQ;
1204 
1205 	ret_val = feature_get(softc_p, feature_csr_offs,
1206 	    feature_elm_inq_reg_offs, subparam, val_p);
1207 
1208 	return (ret_val);
1209 }
1210 
1211 
1212 /*
1213  * param_sharpness_set
1214  */
1215 int
1216 param_sharpness_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1217 {
1218 	int	ret_val;
1219 	uint_t	feature_csr_offs;
1220 
1221 	feature_csr_offs = DCAM1394_REG_OFFS_SHARPNESS_CSR;
1222 
1223 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1224 
1225 	return (ret_val);
1226 }
1227 
1228 
1229 /*
1230  * param_white_balance_get
1231  */
1232 int
1233 param_white_balance_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1234 {
1235 	int	ret_val;
1236 	uint_t	feature_csr_offs;
1237 	uint_t	feature_elm_inq_reg_offs;
1238 
1239 	feature_csr_offs = DCAM1394_REG_OFFS_WHITE_BALANCE_CSR;
1240 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_WHITE_BALANCE_INQ;
1241 
1242 	ret_val = feature_get(softc_p, feature_csr_offs,
1243 	    feature_elm_inq_reg_offs, subparam, val_p);
1244 
1245 	return (ret_val);
1246 }
1247 
1248 
1249 /*
1250  * param_white_balance_set
1251  */
1252 int
1253 param_white_balance_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1254 {
1255 	int	ret_val;
1256 	uint_t	feature_csr_offs;
1257 
1258 	feature_csr_offs = DCAM1394_REG_OFFS_WHITE_BALANCE_CSR;
1259 
1260 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1261 
1262 	return (ret_val);
1263 }
1264 
1265 
1266 /*
1267  * param_hue_get
1268  */
1269 int
1270 param_hue_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1271 {
1272 	int	ret_val;
1273 	uint_t	feature_csr_offs;
1274 	uint_t	feature_elm_inq_reg_offs;
1275 
1276 	feature_csr_offs = DCAM1394_REG_OFFS_HUE_CSR;
1277 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_HUE_INQ;
1278 
1279 	ret_val = feature_get(softc_p, feature_csr_offs,
1280 	    feature_elm_inq_reg_offs, subparam, val_p);
1281 
1282 	return (ret_val);
1283 }
1284 
1285 
1286 /*
1287  * param_hue_set
1288  */
1289 int
1290 param_hue_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1291 {
1292 	int	ret_val;
1293 	uint_t	feature_csr_offs;
1294 
1295 	feature_csr_offs = DCAM1394_REG_OFFS_HUE_CSR;
1296 
1297 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1298 
1299 	return (ret_val);
1300 }
1301 
1302 
1303 /*
1304  * param_saturation_get
1305  */
1306 int
1307 param_saturation_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1308 {
1309 	int	ret_val;
1310 	uint_t	feature_csr_offs;
1311 	uint_t	feature_elm_inq_reg_offs;
1312 
1313 	feature_csr_offs = DCAM1394_REG_OFFS_SATURATION_CSR;
1314 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_SATURATION_INQ;
1315 
1316 	ret_val = feature_get(softc_p, feature_csr_offs,
1317 	    feature_elm_inq_reg_offs, subparam, val_p);
1318 
1319 	return (ret_val);
1320 }
1321 
1322 
1323 /*
1324  * param_saturation_set
1325  */
1326 int
1327 param_saturation_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1328 {
1329 	int	ret_val;
1330 	uint_t	feature_csr_offs;
1331 
1332 	feature_csr_offs = DCAM1394_REG_OFFS_SATURATION_CSR;
1333 
1334 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1335 
1336 	return (ret_val);
1337 }
1338 
1339 
1340 /*
1341  * param_gamma_get
1342  */
1343 int
1344 param_gamma_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1345 {
1346 	int	ret_val;
1347 	uint_t	feature_csr_offs;
1348 	uint_t	feature_elm_inq_reg_offs;
1349 
1350 	feature_csr_offs = DCAM1394_REG_OFFS_GAMMA_CSR;
1351 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_GAMMA_INQ;
1352 
1353 	ret_val = feature_get(softc_p, feature_csr_offs,
1354 	    feature_elm_inq_reg_offs, subparam, val_p);
1355 
1356 	return (ret_val);
1357 }
1358 
1359 
1360 /*
1361  * param_gamma_set
1362  */
1363 int
1364 param_gamma_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1365 {
1366 	int	ret_val;
1367 	uint_t	feature_csr_offs;
1368 
1369 	feature_csr_offs = DCAM1394_REG_OFFS_GAMMA_CSR;
1370 
1371 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1372 
1373 	return (ret_val);
1374 }
1375 
1376 
1377 /*
1378  * param_shutter_get
1379  */
1380 int
1381 param_shutter_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1382 {
1383 	int	ret_val;
1384 	uint_t	feature_csr_offs;
1385 	uint_t	feature_elm_inq_reg_offs;
1386 
1387 	feature_csr_offs = DCAM1394_REG_OFFS_SHUTTER_CSR;
1388 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_SHUTTER_INQ;
1389 
1390 	ret_val = feature_get(softc_p, feature_csr_offs,
1391 	    feature_elm_inq_reg_offs, subparam, val_p);
1392 
1393 	return (ret_val);
1394 }
1395 
1396 
1397 /*
1398  * param_shutter_set
1399  */
1400 int
1401 param_shutter_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1402 {
1403 	int	ret_val;
1404 	uint_t	feature_csr_offs;
1405 
1406 	feature_csr_offs = DCAM1394_REG_OFFS_SHUTTER_CSR;
1407 
1408 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1409 
1410 	return (ret_val);
1411 }
1412 
1413 
1414 /*
1415  * param_gain_get
1416  */
1417 int
1418 param_gain_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1419 {
1420 	int	ret_val;
1421 	uint_t	feature_csr_offs;
1422 	uint_t	feature_elm_inq_reg_offs;
1423 
1424 	feature_csr_offs = DCAM1394_REG_OFFS_GAIN_CSR;
1425 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_GAIN_INQ;
1426 
1427 	ret_val = feature_get(softc_p, feature_csr_offs,
1428 	    feature_elm_inq_reg_offs, subparam, val_p);
1429 
1430 	return (ret_val);
1431 }
1432 
1433 
1434 /*
1435  * param_gain_set
1436  */
1437 int
1438 param_gain_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1439 {
1440 	int	ret_val;
1441 	uint_t	feature_csr_offs;
1442 
1443 	feature_csr_offs = DCAM1394_REG_OFFS_GAIN_CSR;
1444 
1445 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1446 
1447 	return (ret_val);
1448 }
1449 
1450 
1451 /*
1452  * param_iris_get
1453  */
1454 int
1455 param_iris_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1456 {
1457 	int	ret_val;
1458 	uint_t	feature_csr_offs;
1459 	uint_t	feature_elm_inq_reg_offs;
1460 
1461 	feature_csr_offs = DCAM1394_REG_OFFS_IRIS_CSR;
1462 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_IRIS_INQ;
1463 
1464 	ret_val = feature_get(softc_p, feature_csr_offs,
1465 	    feature_elm_inq_reg_offs, subparam, val_p);
1466 
1467 	switch (subparam) {
1468 		case DCAM1394_SUBPARAM_PRESENCE:
1469 			*val_p = 0;
1470 			break;
1471 		case DCAM1394_SUBPARAM_ON_OFF:
1472 			*val_p = 1;
1473 			break;
1474 		case DCAM1394_SUBPARAM_MIN_VAL:
1475 		case DCAM1394_SUBPARAM_MAX_VAL:
1476 		case DCAM1394_SUBPARAM_VALUE:
1477 			*val_p = 4;
1478 			break;
1479 		default:
1480 			break;
1481 	}
1482 
1483 	return (ret_val);
1484 }
1485 
1486 
1487 /*
1488  * param_iris_set
1489  */
1490 int
1491 param_iris_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1492 {
1493 	int	ret_val;
1494 	uint_t	feature_csr_offs;
1495 
1496 	feature_csr_offs = DCAM1394_REG_OFFS_IRIS_CSR;
1497 
1498 	if (subparam == DCAM1394_SUBPARAM_ON_OFF) {
1499 		val = 1;
1500 	} else if (subparam == DCAM1394_SUBPARAM_VALUE) {
1501 		val = 4;
1502 	}
1503 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1504 
1505 	return (ret_val);
1506 }
1507 
1508 
1509 /*
1510  * param_focus_get
1511  */
1512 int
1513 param_focus_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1514 {
1515 	int	ret_val;
1516 	uint_t	feature_csr_offs;
1517 	uint_t	feature_elm_inq_reg_offs;
1518 
1519 	feature_csr_offs = DCAM1394_REG_OFFS_FOCUS_CSR;
1520 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_FOCUS_INQ;
1521 
1522 	ret_val = feature_get(softc_p, feature_csr_offs,
1523 	    feature_elm_inq_reg_offs, subparam, val_p);
1524 
1525 	return (ret_val);
1526 }
1527 
1528 
1529 /*
1530  * param_focus_set
1531  */
1532 int
1533 param_focus_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1534 {
1535 	int	ret_val;
1536 	uint_t	feature_csr_offs;
1537 
1538 	feature_csr_offs = DCAM1394_REG_OFFS_FOCUS_CSR;
1539 
1540 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1541 
1542 	return (ret_val);
1543 }
1544 
1545 
1546 /*
1547  * param_zoom_get
1548  */
1549 int
1550 param_zoom_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1551 {
1552 	int	ret_val;
1553 	uint_t	feature_csr_offs;
1554 	uint_t	feature_elm_inq_reg_offs;
1555 
1556 	feature_csr_offs = DCAM1394_REG_OFFS_ZOOM_CSR;
1557 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_ZOOM_INQ;
1558 
1559 	ret_val = feature_get(softc_p, feature_csr_offs,
1560 	    feature_elm_inq_reg_offs, subparam, val_p);
1561 
1562 	return (ret_val);
1563 }
1564 
1565 
1566 /*
1567  * param_zoom_set
1568  */
1569 int
1570 param_zoom_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1571 {
1572 	int	ret_val;
1573 	uint_t	feature_csr_offs;
1574 
1575 	feature_csr_offs = DCAM1394_REG_OFFS_ZOOM_CSR;
1576 
1577 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1578 
1579 	return (ret_val);
1580 }
1581 
1582 
1583 /*
1584  * param_pan_get
1585  */
1586 int
1587 param_pan_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1588 {
1589 	int	ret_val;
1590 	uint_t	feature_csr_offs;
1591 	uint_t	feature_elm_inq_reg_offs;
1592 
1593 	feature_csr_offs = DCAM1394_REG_OFFS_PAN_CSR;
1594 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_PAN_INQ;
1595 
1596 	ret_val = feature_get(softc_p, feature_csr_offs,
1597 	    feature_elm_inq_reg_offs, subparam, val_p);
1598 
1599 	return (ret_val);
1600 }
1601 
1602 
1603 /*
1604  * param_pan_set
1605  */
1606 int
1607 param_pan_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1608 {
1609 	int	ret_val;
1610 	uint_t	feature_csr_offs;
1611 
1612 	feature_csr_offs = DCAM1394_REG_OFFS_PAN_CSR;
1613 
1614 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1615 
1616 	return (ret_val);
1617 }
1618 
1619 
1620 /*
1621  * param_tilt_get
1622  */
1623 int
1624 param_tilt_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
1625 {
1626 	int	ret_val;
1627 	uint_t	feature_csr_offs;
1628 	uint_t	feature_elm_inq_reg_offs;
1629 
1630 	feature_csr_offs = DCAM1394_REG_OFFS_TILT_CSR;
1631 	feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_TILT_INQ;
1632 
1633 	ret_val = feature_get(softc_p, feature_csr_offs,
1634 	    feature_elm_inq_reg_offs, subparam, val_p);
1635 
1636 	return (ret_val);
1637 }
1638 
1639 
1640 /*
1641  * param_tilt_set
1642  */
1643 int
1644 param_tilt_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
1645 {
1646 	int	ret_val;
1647 	uint_t	feature_csr_offs;
1648 
1649 	feature_csr_offs = DCAM1394_REG_OFFS_TILT_CSR;
1650 
1651 	ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
1652 
1653 	return (ret_val);
1654 }
1655 
1656 
1657 /*
1658  * feature_csr_val_construct
1659  */
1660 static uint_t
1661 feature_csr_val_construct(uint_t subparam, uint_t param_val, uint_t init_val)
1662 {
1663 	uint_t ret_val;
1664 
1665 	switch (subparam) {
1666 
1667 	case DCAM1394_SUBPARAM_ON_OFF:
1668 		ret_val = (init_val & ~(DCAM1394_MASK_ON_OFF)) |
1669 		    (param_val << DCAM1394_SHIFT_ON_OFF);
1670 		break;
1671 
1672 	case DCAM1394_SUBPARAM_CTRL_MODE:
1673 		ret_val = (init_val & ~(DCAM1394_MASK_A_M_MODE)) |
1674 		    (param_val << DCAM1394_SHIFT_A_M_MODE);
1675 		break;
1676 
1677 	case DCAM1394_SUBPARAM_VALUE:
1678 		ret_val = (init_val & ~(DCAM1394_MASK_VALUE)) |
1679 		    (param_val << DCAM1394_SHIFT_VALUE);
1680 		break;
1681 
1682 	case DCAM1394_SUBPARAM_U_VALUE:
1683 		ret_val = (init_val & ~(DCAM1394_MASK_U_VALUE)) |
1684 		    (param_val << DCAM1394_SHIFT_U_VALUE);
1685 		break;
1686 
1687 	case DCAM1394_SUBPARAM_V_VALUE:
1688 		ret_val = (init_val & ~(DCAM1394_MASK_V_VALUE)) |
1689 		    (param_val << DCAM1394_SHIFT_V_VALUE);
1690 		break;
1691 
1692 	default:
1693 		break;
1694 
1695 	}
1696 
1697 	return (ret_val);
1698 }
1699 
1700 
1701 /*
1702  * feature_csr_val_subparam_extract
1703  */
1704 static uint_t
1705 feature_csr_val_subparam_extract(uint_t subparam, uint_t reg_val)
1706 {
1707 	uint_t ret_val;
1708 
1709 	switch (subparam) {
1710 
1711 	case DCAM1394_SUBPARAM_PRESENCE:
1712 		ret_val = (reg_val & DCAM1394_MASK_PRESENCE_INQ) >>
1713 		    DCAM1394_SHIFT_PRESENCE_INQ;
1714 		break;
1715 
1716 	case DCAM1394_SUBPARAM_ON_OFF:
1717 		ret_val = (reg_val & DCAM1394_MASK_ON_OFF) >>
1718 		    DCAM1394_SHIFT_ON_OFF;
1719 		break;
1720 
1721 	case DCAM1394_SUBPARAM_CTRL_MODE:
1722 		ret_val = (reg_val & DCAM1394_MASK_A_M_MODE) >>
1723 		    DCAM1394_SHIFT_A_M_MODE;
1724 		break;
1725 
1726 	case DCAM1394_SUBPARAM_VALUE:
1727 		ret_val = (reg_val & DCAM1394_MASK_VALUE) >>
1728 		    DCAM1394_SHIFT_VALUE;
1729 		break;
1730 
1731 	case DCAM1394_SUBPARAM_U_VALUE:
1732 		ret_val = (reg_val & DCAM1394_MASK_U_VALUE) >>
1733 		    DCAM1394_SHIFT_U_VALUE;
1734 		break;
1735 
1736 	case DCAM1394_SUBPARAM_V_VALUE:
1737 
1738 		ret_val = (reg_val & DCAM1394_MASK_V_VALUE) >>
1739 		    DCAM1394_SHIFT_V_VALUE;
1740 		break;
1741 
1742 	default:
1743 
1744 		ret_val = 0;
1745 
1746 		break;
1747 
1748 	}
1749 
1750 	return (ret_val);
1751 
1752 }
1753 
1754 
1755 /*
1756  * feature_elm_inq_reg_val_subparam_extract
1757  */
1758 static uint_t
1759 feature_elm_inq_reg_val_subparam_extract(uint_t subparam,
1760     uint_t reg_val)
1761 {
1762 	uint_t ret_val;
1763 
1764 	switch (subparam) {
1765 
1766 	case DCAM1394_SUBPARAM_CAP_READ:
1767 		ret_val = (reg_val & DCAM1394_MASK_READOUT_INQ) >>
1768 		    DCAM1394_SHIFT_READOUT_INQ;
1769 		break;
1770 
1771 	case DCAM1394_SUBPARAM_CAP_ON_OFF:
1772 		ret_val = (reg_val & DCAM1394_MASK_ON_OFF_INQ) >>
1773 		    DCAM1394_SHIFT_ON_OFF_INQ;
1774 		break;
1775 
1776 	case DCAM1394_SUBPARAM_CAP_CTRL_AUTO:
1777 		ret_val = (reg_val & DCAM1394_MASK_AUTO_INQ) >>
1778 		    DCAM1394_SHIFT_AUTO_INQ;
1779 		break;
1780 
1781 	case DCAM1394_SUBPARAM_CAP_CTRL_MANUAL:
1782 		ret_val = (reg_val & DCAM1394_MASK_MANUAL_INQ) >>
1783 		    DCAM1394_SHIFT_MANUAL_INQ;
1784 		break;
1785 
1786 	case DCAM1394_SUBPARAM_MIN_VAL:
1787 		ret_val = (reg_val & DCAM1394_MASK_MIN_VAL) >>
1788 		    DCAM1394_SHIFT_MIN_VAL;
1789 		break;
1790 
1791 	case DCAM1394_SUBPARAM_MAX_VAL:
1792 		ret_val = (reg_val & DCAM1394_MASK_MAX_VAL) >>
1793 		    DCAM1394_SHIFT_MAX_VAL;
1794 		break;
1795 
1796 	default:
1797 		ret_val = 0;
1798 		break;
1799 
1800 	}
1801 
1802 	return (ret_val);
1803 }
1804