/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* dcam_param.c
*
* dcam1394 driver. Device parameter access.
*/
#include <sys/1394/targets/dcam1394/dcam.h>
#include <sys/1394/targets/dcam1394/dcam_param.h>
#include <sys/1394/targets/dcam1394/dcam_reg.h>
#include <sys/tnf_probe.h>
/* index by vid_mode */
int g_frame_num_bytes[] = {
57600, /* vid mode 0 */
153600, /* vid mode 1 */
460800, /* vid mode 2 */
614400, /* vid mode 3 */
921600, /* vid mode 4 */
307200 /* vid mode 5 */
};
static uint_t feature_csr_val_construct(uint_t subparam, uint_t param_val,
uint_t init_val);
static uint_t feature_csr_val_subparam_extract(uint_t subparam,
uint_t feature_csr_val);
static uint_t feature_elm_inq_reg_val_subparam_extract(uint_t subparam,
uint_t reg_val);
/*
* param_attr_init
*/
int
param_attr_init(dcam_state_t *softc_p, dcam1394_param_attr_t param_attr)
{
int err, ret_err;
uint_t attr_bmap, cap_on_off, cap_power_ctrl, cap_read;
uint_t param, presence, subparam;
bzero(param_attr, sizeof (dcam1394_param_attr_t));
ret_err = DDI_SUCCESS;
/*
* power ctrl cap
*/
param = DCAM1394_PARAM_CAP_POWER_CTRL;
subparam = DCAM1394_SUBPARAM_NONE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param, subparam, attr_bmap);
/*
* video mode cap
*/
param = DCAM1394_PARAM_CAP_VID_MODE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
for (subparam = DCAM1394_SUBPARAM_VID_MODE_0;
subparam <= DCAM1394_SUBPARAM_VID_MODE_5; subparam++) {
param_attr_set(param_attr, param, subparam, attr_bmap);
}
/*
* frame rate cap
*/
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
for (param = DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_0;
param <= DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_5; param++) {
for (subparam = DCAM1394_SUBPARAM_FRAME_RATE_0;
subparam <= DCAM1394_SUBPARAM_FRAME_RATE_4; subparam++) {
param_attr_set(param_attr, param, subparam, attr_bmap);
}
}
/*
* power
*/
param = DCAM1394_PARAM_POWER;
subparam = DCAM1394_SUBPARAM_NONE;
err = dcam1394_param_get(softc_p, DCAM1394_PARAM_CAP_POWER_CTRL,
DCAM1394_SUBPARAM_NONE, &cap_power_ctrl);
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
if (cap_power_ctrl) {
attr_bmap |= CAP_SET;
}
param_attr_set(param_attr, param, subparam, attr_bmap);
/*
* video mode
*/
param = DCAM1394_PARAM_VID_MODE;
subparam = DCAM1394_SUBPARAM_NONE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET | CAP_SET;
param_attr_set(param_attr, param, subparam, attr_bmap);
/*
* frame rate
*/
param = DCAM1394_PARAM_FRAME_RATE;
subparam = DCAM1394_SUBPARAM_NONE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET | CAP_SET;
param_attr_set(param_attr, param, subparam, attr_bmap);
/*
* ring buffer capacity
*/
param = DCAM1394_PARAM_RING_BUFF_CAPACITY;
subparam = DCAM1394_SUBPARAM_NONE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET | CAP_SET;
param_attr_set(param_attr, param, subparam, attr_bmap);
/*
* ring buffer: num frames ready
*/
param = DCAM1394_PARAM_RING_BUFF_NUM_FRAMES_READY;
subparam = DCAM1394_SUBPARAM_NONE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param, subparam, attr_bmap);
/*
* ring buffer: read ptr increment stride
*/
param = DCAM1394_PARAM_RING_BUFF_READ_PTR_INCR;
subparam = DCAM1394_SUBPARAM_NONE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET | CAP_SET;
param_attr_set(param_attr, param, subparam, attr_bmap);
/*
* frame size
*/
param = DCAM1394_PARAM_FRAME_NUM_BYTES;
subparam = DCAM1394_SUBPARAM_NONE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param, subparam, attr_bmap);
/*
* cam status
*/
param = DCAM1394_PARAM_STATUS;
subparam = DCAM1394_SUBPARAM_NONE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param, subparam, attr_bmap);
/*
* features
*/
for (param = DCAM1394_PARAM_BRIGHTNESS; param <= DCAM1394_PARAM_TILT;
param++) {
/*
* get feature presence
* If the operation to read the parameter fails, then act as
* though the feature is not implemented (because it isn't),
* don't report a DDI failure (as was previously done).
*/
err = dcam1394_param_get(softc_p, param,
DCAM1394_SUBPARAM_PRESENCE, &presence);
if (!err) {
/* feature presence */
subparam = DCAM1394_SUBPARAM_PRESENCE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param, subparam, attr_bmap);
if (presence) {
/* feature cap read */
subparam = DCAM1394_SUBPARAM_CAP_READ;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param,
subparam, attr_bmap);
/* feature cap on/off */
subparam = DCAM1394_SUBPARAM_CAP_ON_OFF;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param,
subparam, attr_bmap);
/* feature cap ctrl auto */
subparam = DCAM1394_SUBPARAM_CAP_CTRL_AUTO;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param,
subparam, attr_bmap);
/* feature cap ctrl manual */
subparam = DCAM1394_SUBPARAM_CAP_CTRL_MANUAL;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param,
subparam, attr_bmap);
/* feature min val */
subparam = DCAM1394_SUBPARAM_MIN_VAL;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param,
subparam, attr_bmap);
/* feature max val */
subparam = DCAM1394_SUBPARAM_MAX_VAL;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
param_attr_set(param_attr, param,
subparam, attr_bmap);
/* feature on/off */
subparam = DCAM1394_SUBPARAM_ON_OFF;
err = dcam1394_param_get(softc_p, param,
DCAM1394_SUBPARAM_CAP_ON_OFF, &cap_on_off);
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET;
if (cap_on_off) {
attr_bmap |= (CAP_SET | CAP_CTRL_SET);
}
param_attr_set(param_attr, param,
subparam, attr_bmap);
/* feature control mode */
subparam = DCAM1394_SUBPARAM_CTRL_MODE;
attr_bmap = IS_VALID | IS_PRESENT | CAP_GET |
CAP_SET | CAP_CTRL_SET;
param_attr_set(param_attr, param,
subparam, attr_bmap);
/* get value read-out capability */
err = dcam1394_param_get(softc_p, param,
DCAM1394_SUBPARAM_CAP_READ,
&cap_read);
if (param == DCAM1394_PARAM_WHITE_BALANCE) {
/*
* white balance feature: u, v value
*/
subparam = DCAM1394_SUBPARAM_U_VALUE;
attr_bmap = IS_VALID | IS_PRESENT |
CAP_SET | CAP_CTRL_SET;
if (cap_read) {
attr_bmap |= CAP_GET;
}
param_attr_set(param_attr, param,
subparam, attr_bmap);
subparam = DCAM1394_SUBPARAM_V_VALUE;
attr_bmap = IS_VALID | IS_PRESENT |
CAP_SET | CAP_CTRL_SET;
if (cap_read) {
attr_bmap |= CAP_GET;
}
param_attr_set(param_attr, param,
subparam, attr_bmap);
} else {
/* feature value */
subparam = DCAM1394_SUBPARAM_VALUE;
attr_bmap = IS_VALID | IS_PRESENT |
CAP_SET | CAP_CTRL_SET;
if (cap_read) {
attr_bmap |= CAP_GET;
}
param_attr_set(param_attr, param,
subparam, attr_bmap);
}
}
}
}
return (ret_err);
}
/*
* param_attr_set
*/
void
param_attr_set(dcam1394_param_attr_t param_attr, uint_t param,
uint_t subparam, uint_t attr_bmap)
{
param_attr[param][subparam] = attr_bmap;
}
/*
* dcam1394_ioctl_param_get
*
* softc's param_attr field must be initialized via param_attr_init()
* before using this function.
*/
int
dcam1394_ioctl_param_get(dcam_state_t *softc_p,
dcam1394_param_list_t param_list)
{
int err, ret_err;
int param, subparam;
uint_t cap_get, is_present, is_valid, val;
ret_err = 0;
for (param = 0; param < DCAM1394_NUM_PARAM; param++) {
for (subparam = 0;
subparam < DCAM1394_NUM_SUBPARAM;
subparam++) {
if (param_list[param][subparam].flag) {
is_valid =
softc_p->param_attr[param][subparam] &
IS_VALID;
is_present =
softc_p->param_attr[param][subparam] &
IS_PRESENT;
cap_get =
softc_p->param_attr[param][subparam] &
CAP_GET;
if (is_valid && is_present && cap_get) {
if (err = dcam1394_param_get(softc_p,
param, subparam, &val)) {
param_list[param][subparam].err = 1;
ret_err = 1;
}
if (!err) {
param_list[param][subparam].val =
val;
}
} else {
param_list[param][subparam].err = 1;
ret_err = 1;
}
}
}
}
return (ret_err);
}
/*
* dcam1394_ioctl_param_set
* softc's param_attr field must be initialized via param_attr_init()
* before using this function.
*/
int
dcam1394_ioctl_param_set(dcam_state_t *softc_p, int is_ctrl_file,
dcam1394_param_list_t param_list)
{
int param, subparam;
int ret_err;
uint_t cap_set, is_present, is_valid, val;
ret_err = 0;
for (param = 0; param < DCAM1394_NUM_PARAM; param++) {
for (subparam = 0;
subparam < DCAM1394_NUM_SUBPARAM;
subparam++) {
if (param_list[param][subparam].flag) {
is_valid =
softc_p->param_attr[param][subparam] &
IS_VALID;
is_present =
softc_p->param_attr[param][subparam] &
IS_PRESENT;
cap_set = is_ctrl_file ?
(softc_p->param_attr[param][subparam]
& CAP_CTRL_SET) :
(softc_p->param_attr[param][subparam]
& CAP_SET);
if (is_valid && is_present && cap_set) {
val = param_list[param][subparam].val;
if (dcam1394_param_set(softc_p,
param, subparam, val)) {
param_list[param][subparam].err = 1;
ret_err = 1;
}
} else {
param_list[param][subparam].err = 1;
ret_err = 1;
}
}
}
}
return (ret_err);
}
/*
* dcam1394_param_get
*/
int
dcam1394_param_get(dcam_state_t *softc_p, uint_t param, uint_t subparam,
uint_t *val_p)
{
int err;
switch (param) {
case DCAM1394_PARAM_CAP_POWER_CTRL:
err = param_cap_power_ctrl_get(softc_p, val_p);
break;
case DCAM1394_PARAM_CAP_VID_MODE:
err = param_cap_vid_mode_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_0:
case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_1:
case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_2:
case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_3:
case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_4:
case DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_5:
err = param_cap_frame_rate_get(softc_p, param, subparam, val_p);
break;
case DCAM1394_PARAM_POWER:
err = param_power_get(softc_p, val_p);
break;
case DCAM1394_PARAM_VID_MODE:
err = param_vid_mode_get(softc_p, val_p);
break;
case DCAM1394_PARAM_FRAME_RATE:
err = param_frame_rate_get(softc_p, val_p);
break;
case DCAM1394_PARAM_RING_BUFF_CAPACITY:
err = param_ring_buff_capacity_get(softc_p, val_p);
break;
case DCAM1394_PARAM_RING_BUFF_NUM_FRAMES_READY:
err = param_ring_buff_num_frames_ready_get(softc_p, val_p);
break;
case DCAM1394_PARAM_RING_BUFF_READ_PTR_INCR:
err = param_ring_buff_read_ptr_incr_get(softc_p, val_p);
break;
case DCAM1394_PARAM_FRAME_NUM_BYTES:
err = param_frame_num_bytes_get(softc_p, val_p);
break;
case DCAM1394_PARAM_STATUS:
err = param_status_get(softc_p, val_p);
break;
case DCAM1394_PARAM_BRIGHTNESS:
err = param_brightness_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_EXPOSURE:
err = param_exposure_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_SHARPNESS:
err = param_sharpness_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_WHITE_BALANCE:
err = param_white_balance_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_HUE:
err = param_hue_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_SATURATION:
err = param_saturation_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_GAMMA:
err = param_gamma_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_SHUTTER:
err = param_shutter_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_GAIN:
err = param_gain_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_IRIS:
err = param_iris_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_FOCUS:
err = param_focus_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_ZOOM:
err = param_zoom_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_PAN:
err = param_pan_get(softc_p, subparam, val_p);
break;
case DCAM1394_PARAM_TILT:
err = param_tilt_get(softc_p, subparam, val_p);
break;
default:
err = 1;
break;
}
return (err);
}
/*
* dcam1394_param_set
*/
int
dcam1394_param_set(dcam_state_t *softc_p, uint_t param, uint_t subparam,
uint_t val)
{
int err;
switch (param) {
case DCAM1394_PARAM_POWER:
err = param_power_set(softc_p, val);
break;
case DCAM1394_PARAM_VID_MODE:
err = param_vid_mode_set(softc_p, val);
break;
case DCAM1394_PARAM_FRAME_RATE:
err = param_frame_rate_set(softc_p, val);
break;
case DCAM1394_PARAM_RING_BUFF_CAPACITY:
err = param_ring_buff_capacity_set(softc_p, val);
break;
case DCAM1394_PARAM_RING_BUFF_READ_PTR_INCR:
err = param_ring_buff_read_ptr_incr_set(softc_p, val);
break;
case DCAM1394_PARAM_BRIGHTNESS:
err = param_brightness_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_EXPOSURE:
err = param_exposure_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_SHARPNESS:
err = param_sharpness_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_WHITE_BALANCE:
err = param_white_balance_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_HUE:
err = param_hue_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_SATURATION:
err = param_saturation_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_GAMMA:
err = param_gamma_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_SHUTTER:
err = param_shutter_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_GAIN:
err = param_gain_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_IRIS:
err = param_iris_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_FOCUS:
err = param_focus_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_ZOOM:
err = param_zoom_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_PAN:
err = param_pan_set(softc_p, subparam, val);
break;
case DCAM1394_PARAM_TILT:
err = param_tilt_set(softc_p, subparam, val);
break;
default:
err = 1;
break;
}
return (err);
}
/*
* feature_get
*/
int
feature_get(dcam_state_t *softc_p, uint_t feature_csr_offs,
uint_t feature_elm_inq_reg_offs, uint_t subparam, uint_t *val_p)
{
dcam1394_reg_io_t reg_io;
uint_t val;
switch (subparam) {
case DCAM1394_SUBPARAM_PRESENCE:
case DCAM1394_SUBPARAM_ON_OFF:
case DCAM1394_SUBPARAM_CTRL_MODE:
case DCAM1394_SUBPARAM_VALUE:
case DCAM1394_SUBPARAM_U_VALUE:
case DCAM1394_SUBPARAM_V_VALUE:
reg_io.offs = feature_csr_offs +
DCAM1394_REG_OFFS_FEATURE_CSR_BASE;
if (dcam_reg_read(softc_p, &reg_io)) {
return (1);
}
val = feature_csr_val_subparam_extract(subparam, reg_io.val);
break;
case DCAM1394_SUBPARAM_CAP_READ:
case DCAM1394_SUBPARAM_CAP_ON_OFF:
case DCAM1394_SUBPARAM_CAP_CTRL_AUTO:
case DCAM1394_SUBPARAM_CAP_CTRL_MANUAL:
case DCAM1394_SUBPARAM_MIN_VAL:
case DCAM1394_SUBPARAM_MAX_VAL:
reg_io.offs = feature_elm_inq_reg_offs +
DCAM1394_REG_OFFS_FEATURE_ELM_INQ_BASE;
if (dcam_reg_read(softc_p, &reg_io)) {
return (1);
}
val = feature_elm_inq_reg_val_subparam_extract(subparam,
reg_io.val);
break;
default:
return (1);
}
*val_p = val;
return (0);
}
/*
* feature_set
*/
int
feature_set(dcam_state_t *softc_p, uint_t feature_csr_offs,
uint_t subparam, uint_t val)
{
dcam1394_reg_io_t reg_io;
reg_io.offs = feature_csr_offs + DCAM1394_REG_OFFS_FEATURE_CSR_BASE;
if (dcam_reg_read(softc_p, &reg_io)) {
return (1);
}
reg_io.val = feature_csr_val_construct(subparam, val, reg_io.val);
if (dcam_reg_write(softc_p, &reg_io)) {
return (1);
}
return (0);
}
/*
* param_cap_power_ctrl_get
*/
int
param_cap_power_ctrl_get(dcam_state_t *softc_p, uint_t *val_p)
{
dcam1394_reg_io_t reg_io;
reg_io.offs = DCAM1394_REG_OFFS_BASIC_FUNC_INQ;
if (dcam_reg_read(softc_p, &reg_io)) {
return (1);
}
*val_p = (reg_io.val & DCAM1394_MASK_CAM_POWER_CTRL) >>
DCAM1394_SHIFT_CAM_POWER_CTRL;
return (0);
}
/*
* param_cap_vid_mode_get
* dcam spec: sec 1.2.1.1
*/
int
param_cap_vid_mode_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
dcam1394_reg_io_t reg_io;
uint_t mask, shift, vid_mode;
vid_mode = subparam - DCAM1394_SUBPARAM_VID_MODE_0;
reg_io.offs = DCAM1394_REG_OFFS_VID_MODE_INQ;
if (dcam_reg_read(softc_p, &reg_io)) {
return (1);
}
mask = 1 << (31 - vid_mode);
shift = 31 - vid_mode;
*val_p = (reg_io.val & mask) >> shift;
return (0);
}
/*
* param_cap_frame_rate_get()
* dcam spec: sec 1.2.2
*/
int
param_cap_frame_rate_get(dcam_state_t *softc_p, uint_t param,
uint_t subparam, uint_t *val_p)
{
dcam1394_reg_io_t reg_io;
uint_t frame_rate, mask, shift, vid_mode;
vid_mode = param - DCAM1394_PARAM_CAP_FRAME_RATE_VID_MODE_0;
frame_rate = subparam - DCAM1394_SUBPARAM_FRAME_RATE_0;
reg_io.offs = DCAM1394_REG_OFFS_FRAME_RATE_INQ_BASE + (4 * vid_mode);
if (dcam_reg_read(softc_p, &reg_io)) {
return (1);
}
mask = 1 << (31 - (frame_rate + 1));
shift = 31 - (frame_rate + 1);
*val_p = (reg_io.val & mask) >> shift;
return (0);
}
/*
* param_power_get
*/
int
param_power_get(dcam_state_t *softc_p, uint_t *val_p)
{
dcam1394_reg_io_t reg_io;
reg_io.offs = DCAM1394_REG_OFFS_CAMERA_POWER;
if (dcam_reg_read(softc_p, &reg_io)) {
return (1);
}
*val_p = reg_io.val >> DCAM1394_SHIFT_CAMERA_POWER;
return (0);
}
/*
* param_power_set()
*/
int
param_power_set(dcam_state_t *softc_p, uint_t val)
{
dcam1394_reg_io_t reg_io;
reg_io.offs = DCAM1394_REG_OFFS_CAMERA_POWER;
reg_io.val = val << DCAM1394_SHIFT_CAMERA_POWER;
if (dcam_reg_write(softc_p, &reg_io)) {
return (1);
}
return (0);
}
/*
* param_vid_mode_get
*/
int
param_vid_mode_get(dcam_state_t *softc_p, uint_t *val_p)
{
dcam1394_reg_io_t reg_io;
reg_io.offs = DCAM1394_REG_OFFS_CUR_V_MODE;
if (dcam_reg_read(softc_p, &reg_io)) {
return (1);
}
*val_p = reg_io.val >> DCAM1394_SHIFT_CUR_V_MODE;
return (0);
}
/*
* param_vid_mode_set
*/
int
param_vid_mode_set(dcam_state_t *softc_p, uint_t val)
{
dcam1394_reg_io_t reg_io;
uint_t vid_mode;
vid_mode = val - DCAM1394_VID_MODE_0;
reg_io.offs = DCAM1394_REG_OFFS_CUR_V_MODE;
reg_io.val = vid_mode << DCAM1394_SHIFT_CUR_V_MODE;
if (dcam_reg_write(softc_p, &reg_io)) {
return (1);
}
softc_p->cur_vid_mode = val;
/*
* if we are currently receiving frames, we need to do a restart
* so that the new vid mode value takes effect
*/
if (softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT) {
(void) dcam_frame_rcv_stop(softc_p);
(void) dcam1394_ioctl_frame_rcv_start(softc_p);
}
return (0);
}
/*
* param_frame_rate_get
*/
int
param_frame_rate_get(dcam_state_t *softc_p, uint_t *val_p)
{
dcam1394_reg_io_t reg_io;
uint_t frame_rate;
reg_io.offs = DCAM1394_REG_OFFS_CUR_V_FRM_RATE;
if (dcam_reg_read(softc_p, &reg_io)) {
return (1);
}
frame_rate = reg_io.val >> DCAM1394_SHIFT_CUR_V_FRM_RATE;
*val_p = frame_rate - 1 + DCAM1394_FRAME_RATE_0;
return (0);
}
/*
* param_frame_rate_set
*/
int
param_frame_rate_set(dcam_state_t *softc_p, uint_t val)
{
dcam1394_reg_io_t reg_io;
uint_t frame_rate;
/* if we are currently receiving frames, stop the camera */
if (softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT) {
(void) dcam_frame_rcv_stop(softc_p);
frame_rate = val - DCAM1394_FRAME_RATE_0 + 1;
reg_io.offs = DCAM1394_REG_OFFS_CUR_V_FRM_RATE;
reg_io.val = frame_rate << DCAM1394_SHIFT_CUR_V_FRM_RATE;
if (dcam_reg_write(softc_p, &reg_io)) {
return (1);
}
/*
* Update the state info.
* note: the driver maintains frame rate in an array
* whereas the the camera uses predefined values whose
* lowest frame rate starts at 6
*/
softc_p->cur_frame_rate = val - 6;
/* restart the camera */
(void) dcam1394_ioctl_frame_rcv_start(softc_p);
} else {
frame_rate = val - DCAM1394_FRAME_RATE_0 + 1;
reg_io.offs = DCAM1394_REG_OFFS_CUR_V_FRM_RATE;
reg_io.val = frame_rate << DCAM1394_SHIFT_CUR_V_FRM_RATE;
if (dcam_reg_write(softc_p, &reg_io)) {
return (1);
}
/* see note above re skewing of value by 6 */
softc_p->cur_frame_rate = val - 6;
}
return (0);
}
/*
* param_ring_buff_capacity_get()
*/
int
param_ring_buff_capacity_get(dcam_state_t *softc_p, uint_t *val_p)
{
*val_p = softc_p->cur_ring_buff_capacity;
return (0);
}
/*
* param_ring_buff_capacity_set
*/
int
param_ring_buff_capacity_set(dcam_state_t *softc_p, uint_t val)
{
/* bounds check */
if ((val < 2) || (val > 30)) {
return (1);
}
/* update our state info */
softc_p->cur_ring_buff_capacity = val;
/*
* if we are currently receiving frames, we need to do a restart
* so that the new buff_capacity value takes effect
*/
if (softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT) {
(void) dcam_frame_rcv_stop(softc_p);
(void) dcam1394_ioctl_frame_rcv_start(softc_p);
}
return (0);
}
/*
* param_ring_buff_num_frames_ready_get()
*/
int
param_ring_buff_num_frames_ready_get(dcam_state_t *softc_p, uint_t *val_p)
{
size_t read_pos, write_pos;
/*
* note: currently we support only one read_ptr_id, so the
* following logic will work. If multiple read_ptr_id's are
* supported, this function call will need to receive a
* read_ptr_id
*/
if (softc_p->ring_buff_p == NULL) {
return (1);
}
mutex_enter(&softc_p->dcam_frame_is_done_mutex);
read_pos = ring_buff_read_ptr_pos_get(softc_p->ring_buff_p, 0);
write_pos = ring_buff_write_ptr_pos_get(softc_p->ring_buff_p);
if (read_pos < write_pos) {
*val_p = write_pos - read_pos;
} else {
*val_p = (softc_p->ring_buff_p->num_buffs + write_pos) -
read_pos;
}
mutex_exit(&softc_p->dcam_frame_is_done_mutex);
return (0);
}
/*
* param_ring_buff_read_ptr_incr_get()
*/
int
param_ring_buff_read_ptr_incr_get(dcam_state_t *softc_p, uint_t *val_p)
{
if (softc_p->ring_buff_p == NULL) {
return (1);
}
*val_p = softc_p->ring_buff_p->read_ptr_incr_val;
return (0);
}
/*
* param_ring_buff_read_ptr_incr_set
*/
int
param_ring_buff_read_ptr_incr_set(dcam_state_t *softc_p, uint_t val)
{
if (softc_p->ring_buff_p == NULL) {
return (1);
}
softc_p->ring_buff_p->read_ptr_incr_val = val;
return (0);
}
/*
* param_frame_num_bytes_get
*/
int
param_frame_num_bytes_get(dcam_state_t *softc_p, uint_t *val_p)
{
if (softc_p == NULL) {
return (1);
}
*val_p = g_frame_num_bytes[softc_p->cur_vid_mode];
return (0);
}
/*
* param_status_get()
*/
int
param_status_get(dcam_state_t *softc_p, uint_t *val_p)
{
mutex_enter(&softc_p->dcam_frame_is_done_mutex);
*val_p = softc_p->param_status;
softc_p->param_status = 0;
mutex_exit(&softc_p->dcam_frame_is_done_mutex);
return (0);
}
/*
* param_brightness_get
*/
int
param_brightness_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_BRIGHTNESS_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_BRIGHTNESS_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_brightness_set()
*/
int
param_brightness_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_BRIGHTNESS_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_exposure_get
*/
int
param_exposure_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_EXPOSURE_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_EXPOSURE_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_exposure_set
*/
int
param_exposure_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_EXPOSURE_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_sharpness_get
*/
int
param_sharpness_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_SHARPNESS_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_SHARPNESS_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_sharpness_set
*/
int
param_sharpness_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_SHARPNESS_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_white_balance_get
*/
int
param_white_balance_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_WHITE_BALANCE_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_WHITE_BALANCE_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_white_balance_set
*/
int
param_white_balance_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_WHITE_BALANCE_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_hue_get
*/
int
param_hue_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_HUE_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_HUE_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_hue_set
*/
int
param_hue_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_HUE_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_saturation_get
*/
int
param_saturation_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_SATURATION_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_SATURATION_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_saturation_set
*/
int
param_saturation_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_SATURATION_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_gamma_get
*/
int
param_gamma_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_GAMMA_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_GAMMA_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_gamma_set
*/
int
param_gamma_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_GAMMA_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_shutter_get
*/
int
param_shutter_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_SHUTTER_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_SHUTTER_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_shutter_set
*/
int
param_shutter_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_SHUTTER_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_gain_get
*/
int
param_gain_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_GAIN_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_GAIN_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_gain_set
*/
int
param_gain_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_GAIN_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_iris_get
*/
int
param_iris_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_IRIS_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_IRIS_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
switch (subparam) {
case DCAM1394_SUBPARAM_PRESENCE:
*val_p = 0;
break;
case DCAM1394_SUBPARAM_ON_OFF:
*val_p = 1;
break;
case DCAM1394_SUBPARAM_MIN_VAL:
case DCAM1394_SUBPARAM_MAX_VAL:
case DCAM1394_SUBPARAM_VALUE:
*val_p = 4;
break;
default:
break;
}
return (ret_val);
}
/*
* param_iris_set
*/
int
param_iris_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_IRIS_CSR;
if (subparam == DCAM1394_SUBPARAM_ON_OFF) {
val = 1;
} else if (subparam == DCAM1394_SUBPARAM_VALUE) {
val = 4;
}
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_focus_get
*/
int
param_focus_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_FOCUS_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_FOCUS_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_focus_set
*/
int
param_focus_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_FOCUS_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_zoom_get
*/
int
param_zoom_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_ZOOM_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_ZOOM_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_zoom_set
*/
int
param_zoom_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_ZOOM_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_pan_get
*/
int
param_pan_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_PAN_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_PAN_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_pan_set
*/
int
param_pan_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_PAN_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* param_tilt_get
*/
int
param_tilt_get(dcam_state_t *softc_p, uint_t subparam, uint_t *val_p)
{
int ret_val;
uint_t feature_csr_offs;
uint_t feature_elm_inq_reg_offs;
feature_csr_offs = DCAM1394_REG_OFFS_TILT_CSR;
feature_elm_inq_reg_offs = DCAM1394_REG_OFFS_TILT_INQ;
ret_val = feature_get(softc_p, feature_csr_offs,
feature_elm_inq_reg_offs, subparam, val_p);
return (ret_val);
}
/*
* param_tilt_set
*/
int
param_tilt_set(dcam_state_t *softc_p, uint_t subparam, uint_t val)
{
int ret_val;
uint_t feature_csr_offs;
feature_csr_offs = DCAM1394_REG_OFFS_TILT_CSR;
ret_val = feature_set(softc_p, feature_csr_offs, subparam, val);
return (ret_val);
}
/*
* feature_csr_val_construct
*/
static uint_t
feature_csr_val_construct(uint_t subparam, uint_t param_val, uint_t init_val)
{
uint_t ret_val;
switch (subparam) {
case DCAM1394_SUBPARAM_ON_OFF:
ret_val = (init_val & ~(DCAM1394_MASK_ON_OFF)) |
(param_val << DCAM1394_SHIFT_ON_OFF);
break;
case DCAM1394_SUBPARAM_CTRL_MODE:
ret_val = (init_val & ~(DCAM1394_MASK_A_M_MODE)) |
(param_val << DCAM1394_SHIFT_A_M_MODE);
break;
case DCAM1394_SUBPARAM_VALUE:
ret_val = (init_val & ~(DCAM1394_MASK_VALUE)) |
(param_val << DCAM1394_SHIFT_VALUE);
break;
case DCAM1394_SUBPARAM_U_VALUE:
ret_val = (init_val & ~(DCAM1394_MASK_U_VALUE)) |
(param_val << DCAM1394_SHIFT_U_VALUE);
break;
case DCAM1394_SUBPARAM_V_VALUE:
ret_val = (init_val & ~(DCAM1394_MASK_V_VALUE)) |
(param_val << DCAM1394_SHIFT_V_VALUE);
break;
default:
break;
}
return (ret_val);
}
/*
* feature_csr_val_subparam_extract
*/
static uint_t
feature_csr_val_subparam_extract(uint_t subparam, uint_t reg_val)
{
uint_t ret_val;
switch (subparam) {
case DCAM1394_SUBPARAM_PRESENCE:
ret_val = (reg_val & DCAM1394_MASK_PRESENCE_INQ) >>
DCAM1394_SHIFT_PRESENCE_INQ;
break;
case DCAM1394_SUBPARAM_ON_OFF:
ret_val = (reg_val & DCAM1394_MASK_ON_OFF) >>
DCAM1394_SHIFT_ON_OFF;
break;
case DCAM1394_SUBPARAM_CTRL_MODE:
ret_val = (reg_val & DCAM1394_MASK_A_M_MODE) >>
DCAM1394_SHIFT_A_M_MODE;
break;
case DCAM1394_SUBPARAM_VALUE:
ret_val = (reg_val & DCAM1394_MASK_VALUE) >>
DCAM1394_SHIFT_VALUE;
break;
case DCAM1394_SUBPARAM_U_VALUE:
ret_val = (reg_val & DCAM1394_MASK_U_VALUE) >>
DCAM1394_SHIFT_U_VALUE;
break;
case DCAM1394_SUBPARAM_V_VALUE:
ret_val = (reg_val & DCAM1394_MASK_V_VALUE) >>
DCAM1394_SHIFT_V_VALUE;
break;
default:
ret_val = 0;
break;
}
return (ret_val);
}
/*
* feature_elm_inq_reg_val_subparam_extract
*/
static uint_t
feature_elm_inq_reg_val_subparam_extract(uint_t subparam,
uint_t reg_val)
{
uint_t ret_val;
switch (subparam) {
case DCAM1394_SUBPARAM_CAP_READ:
ret_val = (reg_val & DCAM1394_MASK_READOUT_INQ) >>
DCAM1394_SHIFT_READOUT_INQ;
break;
case DCAM1394_SUBPARAM_CAP_ON_OFF:
ret_val = (reg_val & DCAM1394_MASK_ON_OFF_INQ) >>
DCAM1394_SHIFT_ON_OFF_INQ;
break;
case DCAM1394_SUBPARAM_CAP_CTRL_AUTO:
ret_val = (reg_val & DCAM1394_MASK_AUTO_INQ) >>
DCAM1394_SHIFT_AUTO_INQ;
break;
case DCAM1394_SUBPARAM_CAP_CTRL_MANUAL:
ret_val = (reg_val & DCAM1394_MASK_MANUAL_INQ) >>
DCAM1394_SHIFT_MANUAL_INQ;
break;
case DCAM1394_SUBPARAM_MIN_VAL:
ret_val = (reg_val & DCAM1394_MASK_MIN_VAL) >>
DCAM1394_SHIFT_MIN_VAL;
break;
case DCAM1394_SUBPARAM_MAX_VAL:
ret_val = (reg_val & DCAM1394_MASK_MAX_VAL) >>
DCAM1394_SHIFT_MAX_VAL;
break;
default:
ret_val = 0;
break;
}
return (ret_val);
}