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_reg.c
31 *
32 * dcam1394 driver.  Control register access support.
33 */
34
35#include <sys/tnf_probe.h>
36#include <sys/1394/targets/dcam1394/dcam_reg.h>
37
38
39/*
40 * dcam_reg_read
41 */
42int
43dcam_reg_read(dcam_state_t *soft_state, dcam1394_reg_io_t *arg)
44{
45	cmd1394_cmd_t	*cmdp;
46
47	if (t1394_alloc_cmd(soft_state->sl_handle, 1, &cmdp) != DDI_SUCCESS) {
48		return (-1);
49	}
50
51	cmdp->cmd_type = CMD1394_ASYNCH_RD_QUAD;
52	cmdp->cmd_addr = 0x0000FFFFF0F00000 |
53	    (uint64_t)(arg->offs & 0x00000FFC);
54	cmdp->cmd_options = CMD1394_BLOCKING;
55
56#ifdef GRAPHICS_DELAY
57	/*
58	 * This delay should not be necessary, but was added for some
59	 * unknown reason.  Should it ever be determined that it
60	 * is necessary, this delay should be reenabled.
61	 */
62	delay(drv_usectohz(500));
63#endif
64
65	if (t1394_read(soft_state->sl_handle, cmdp) != DDI_SUCCESS) {
66		(void) t1394_free_cmd(soft_state->sl_handle, 0, &cmdp);
67		return (-1);
68	}
69
70	if (cmdp->cmd_result != DDI_SUCCESS) {
71		(void) t1394_free_cmd(soft_state->sl_handle, 0, &cmdp);
72		return (-1);
73	}
74
75	/* perform endian adjustment */
76	cmdp->cmd_u.q.quadlet_data = T1394_DATA32(cmdp->cmd_u.q.quadlet_data);
77	arg->val = cmdp->cmd_u.q.quadlet_data;
78
79	(void) t1394_free_cmd(soft_state->sl_handle, 0, &cmdp);
80
81	return (0);
82}
83
84
85/*
86 * dcam_reg_write
87 */
88int
89dcam_reg_write(dcam_state_t *soft_state, dcam1394_reg_io_t *arg)
90{
91	cmd1394_cmd_t	*cmdp;
92
93	if (t1394_alloc_cmd(soft_state->sl_handle, 0, &cmdp) != DDI_SUCCESS) {
94		return (-1);
95	}
96
97	cmdp->cmd_type = CMD1394_ASYNCH_WR_QUAD;
98	cmdp->cmd_addr = 0x0000FFFFF0F00000 |
99	    (uint64_t)(arg->offs & 0x00000FFC);
100	cmdp->cmd_options = CMD1394_BLOCKING;
101
102	/* perform endian adjustment */
103	cmdp->cmd_u.q.quadlet_data = T1394_DATA32(arg->val);
104
105#ifdef GRAPHICS_DELAY
106	/*
107	 * See the description in dcam_reg_read() above.
108	 */
109	delay(drv_usectohz(500));
110#endif
111
112	if (t1394_write(soft_state->sl_handle, cmdp) != DDI_SUCCESS) {
113		(void) t1394_free_cmd(soft_state->sl_handle, 0, &cmdp);
114		return (-1);
115	}
116
117	if (cmdp->cmd_result != DDI_SUCCESS) {
118		(void) t1394_free_cmd(soft_state->sl_handle, 0, &cmdp);
119		return (-1);
120	}
121
122	(void) t1394_free_cmd(soft_state->sl_handle, 0, &cmdp);
123
124	return (0);
125}
126