]> git.saurik.com Git - apple/xnu.git/blob - iokit/Families/IOHIDSystem/IOHIDDescriptorParser/HIDPutData.c
3eceaac1c684f63e73deedd1ab441e9e1177021e
[apple/xnu.git] / iokit / Families / IOHIDSystem / IOHIDDescriptorParser / HIDPutData.c
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 File: HIDPutData.c
24
25 Contains: xxx put contents here xxx
26
27 Version: xxx put version here xxx
28
29 Copyright: © 1999-2000 by Apple Computer, Inc., all rights reserved.
30
31 File Ownership:
32
33 DRI: xxx put dri here xxx
34
35 Other Contact: xxx put other contact here xxx
36
37 Technology: xxx put technology here xxx
38
39 Writers:
40
41 (BWS) Brent Schorsch
42 (KH) Keithen Hayenga
43
44 Change History (most recent first):
45
46 <USB3> 12/12/00 KH Correcct cast of void *
47 <USB2> 11/11/99 KH Use shifted value when HIDSetUsageValue fills data into a report
48 field that spans multiple bytes.
49 <USB2> 11/10/99 KH Data that overflowed byte bounderies was lost because
50 we shifted initial value instead of value corrected for
51 starting bit location.
52 <USB1> 3/5/99 BWS first checked in
53 */
54
55 #include "HIDLib.h"
56
57 //#include <stdio.h>
58
59 /*
60 *------------------------------------------------------------------------------
61 *
62 * HIDPutData - Put a single data item to a report
63 *
64 * Input:
65 * psReport - The report
66 * iReportLength - The length of the report
67 * iStart - Start Bit in report
68 * iSize - Number of Bits
69 * iValue - The data
70 * Output:
71 * Returns:
72 * kHidP_Success - Success
73 * kHidP_NullPointer - Argument, Pointer was Null
74 *
75 *------------------------------------------------------------------------------
76 */
77 OSStatus
78 HIDPutData (void * report,
79 ByteCount reportLength,
80 UInt32 start,
81 UInt32 size,
82 SInt32 value)
83 {
84 Byte * psReport = (Byte *)report;
85 SInt32 data, iShiftedData;
86 UInt32 iStartByte, startBit;
87 UInt32 iLastByte, iLastBit;
88 UInt32 iStartMask, iLastMask;
89 UInt32 iDataMask;
90 /*
91 * Report
92 * Bit 28 27 26 25 24 | 23 22 21 20 19 18 17 16 | 15 14 13 12 11 10 09 ...
93 * Last Byte (3) | | Byte 2 | | Start Byte (1)
94 * Data x x x d d | d d d d d d d d | d d y y y y y
95 * Last Bit (1) / | | \ Start Bit (6)
96 * ... 1 1 1 0 0 | Intermediate | 0 0 1 1 1 1 1 ...
97 * Last Mask | Byte(s) | StartMask
98 */
99 iLastByte = (start + size - 1)/8;
100 /*
101 * Check the parameters
102 */
103 if ((start < 0) || (size <= 0) || (iLastByte >= reportLength))
104 return kHIDBadParameterErr;
105 iLastBit = (start + size - 1)&7;
106 iLastMask = ~((1<<(iLastBit+1)) - 1);
107 iStartByte = start/8;
108 startBit = start&7;
109 iStartMask = (1<<startBit) - 1;
110 /*
111 * If the data is contained in one byte then
112 * handle it differently
113 * Mask off just the area where the new data goes
114 * Shift the data over to its new location
115 * Mask the data for its new location
116 * Or in the data
117 */
118 if (iStartByte == iLastByte)
119 {
120 data = psReport[iStartByte];
121 iDataMask = iStartMask | iLastMask;
122 data &= iDataMask;
123 iShiftedData = value << startBit;
124 iShiftedData &= ~iDataMask;
125 data |= iShiftedData;
126 }
127 /*
128 * If the data is in more than one byte then
129 * Do the start byte first
130 * Mask off the bits where the new data goes
131 * Shift the new data over to the start of field
132 * Or the two together and store back out
133 */
134 else
135 {
136 data = psReport[iStartByte];
137 data &= iStartMask;
138 iShiftedData = value << startBit;
139 data |= iShiftedData;
140 psReport[iStartByte] = (Byte) data;
141 iShiftedData >>= 8;
142 /*
143 * Store out an intermediate bytes
144 */
145 while (++iStartByte < iLastByte)
146 {
147 psReport[iStartByte] = (Byte) iShiftedData;
148 iShiftedData >>= 8;
149 }
150 /*
151 * Mask off the bits where the new data goes
152 * Mask off the bits in the new data where the old goes
153 * Or the two together and store back out
154 */
155 data = psReport[iLastByte];
156 data &= iLastMask;
157 iShiftedData &= ~iLastMask;
158 data |= iShiftedData;
159 }
160 /*
161 * Store out the last or only Byte
162 */
163 psReport[iStartByte] = (Byte) data;
164 return kHIDSuccess;
165 }
166