Ticket #235: 6200ch.c

File 6200ch.c, 6.7 KB (added by Mike Cannon <m_cannon@…>, 20 years ago)

Try this.

Line 
1/*
2 * 6200ch - an external channel changer for Motorola DCT-6200 Tuner
3 *
4 * Copyright 2004,2005 by Stacey D. Son <mythdev@son.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#include <libavc1394/rom1394.h>
22#include <libavc1394/avc1394.h>
23#include <libraw1394/raw1394.h>
24#include <sys/types.h>
25#include <stdio.h>
26#include <errno.h>
27#include <stdlib.h>
28
29// Motorola DCT-6200 IDs
30// Note: there are too many vendor IDs for the 6200
31#define DCT6200_VENDOR_ID1 0x00000ce5
32#define DCT6200_VENDOR_ID2 0x00000e5c
33#define DCT6200_VENDOR_ID3 0x00001225
34#define DCT6200_VENDOR_ID4 0x00000f9f
35#define DCT6200_VENDOR_ID5 0x00001180
36#define DCT6200_VENDOR_ID6 0x000012c9
37#define DCT6412_VENDOR_ID1 0x00000f9f
38
39int vendor_ids[] = { -1, // Specified by -V
40 DCT6200_VENDOR_ID1,
41 DCT6200_VENDOR_ID2,
42 DCT6200_VENDOR_ID3,
43 DCT6200_VENDOR_ID4,
44 DCT6200_VENDOR_ID5,
45 DCT6200_VENDOR_ID6,
46 DCT6412_VENDOR_ID1
47 };
48int get_vendor (int vid) {
49 int last = sizeof(vendor_ids) / sizeof(int);
50 int i;
51 for (i = 0; i < last; i++) {
52 if (vid == vendor_ids[i])
53 return 1;
54 }
55 return 0;
56}
57
58
59#define DCT6200_MODEL_ID1 0x0000620a
60#define DCT6200_MODEL_ID2 0x00006200
61#define DCT6412_MODEL_ID1 0x000064ca
62#define DCT6208_MODEL_ID1 0x0000628a
63int model_ids[] = {-1, // Specified by -M
64 DCT6200_MODEL_ID1,
65 DCT6200_MODEL_ID2,
66 DCT6412_MODEL_ID1
67 // ,
68 // DCT6208_MODEL_ID1
69 };
70
71int get_model (int mid) {
72 int last = sizeof(model_ids) / sizeof(int);
73 int i;
74 for (i = 0; i < last; i++) {
75 if (mid == model_ids[i])
76 return 1;
77 }
78 return 0;
79}
80
81#define DCT6200_SPEC_ID 0x00005068
82#define DCT6200_SW_VERSION 0x00010101
83
84
85#define AVC1394_SUBUNIT_TYPE_6200 (9 << 19) /* uses a reserved subunit type */
86
87#define AVC1394_6200_COMMAND_CHANNEL 0x000007C00 /* 6200 subunit command */
88#define AVC1394_6200_OPERAND_SET 0x20 /* 6200 subunit command operand */
89
90#define CTL_CMD0 AVC1394_CTYPE_CONTROL | AVC1394_SUBUNIT_TYPE_6200 | \
91 AVC1394_SUBUNIT_ID_0 | AVC1394_6200_COMMAND_CHANNEL | \
92 AVC1394_6200_OPERAND_SET
93
94
95void usage()
96{
97 fprintf(stderr, "Usage: 6200ch [-v] [-p n] <channel_num>\n");
98 exit(1);
99}
100
101int main (int argc, char *argv[])
102{
103 rom1394_directory dir;
104 int device = -1;
105 int i;
106 int verbose = 0;
107 int port = 0;
108 quadlet_t cmd[2];
109 int dig[3];
110 int chn = 0;
111
112 if (argc < 2)
113 usage();
114
115 argc--;
116 argv++;
117
118 while (argc > 0) {
119 if (argv[0][0] == '-' && argv[0][1] == 'h') {
120 usage();
121 }
122 if (argv[0][0] == '-' && argv[0][1] == 'v') {
123 verbose = 1;
124 argc--;
125 argv++;
126 continue;;
127 }
128 if (argv[0][0] == '-' && argv[0][1] == 'p') {
129 argc--;
130 argv++;
131 if (argc > 0) {
132 port = atoi (argv[0]);
133 argc--;
134 argv++;
135 }
136 continue;
137 }
138 if (argv[0][0] == '-' && argv[0][1] == 'V') {
139 argc--;
140 argv++;
141 if (argc > 0) {
142 sscanf (argv[0], "%i", &vendor_ids[0]);
143 argc--;
144 argv++;
145 }
146 continue;
147 }
148 if (argv[0][0] == '-' && argv[0][1] == 'M') {
149 argc--;
150 argv++;
151 if (argc > 0) {
152 sscanf (argv[0], "%i", &model_ids[0]);
153 argc--;
154 argv++;
155 }
156 continue;
157 }
158 if (argc == 1) {
159 chn = atoi(argv[0]);
160 argc--;
161 argv++;
162 }
163 else
164 usage();
165 }
166
167
168#ifdef RAW1394_V_0_8
169 raw1394handle_t handle = raw1394_get_handle();
170#else
171 raw1394handle_t handle = raw1394_new_handle();
172#endif
173
174 if (!handle) {
175 if (!errno) {
176 fprintf(stderr, "Not Compatable!\n");
177 } else {
178 perror("Couldn't get 1394 handle");
179 fprintf(stderr, "Is ieee1394, driver, and raw1394 loaded?\n");
180 }
181 exit(1);
182 }
183
184 if (raw1394_set_port(handle, port) < 0) {
185 perror("Couldn't set port.\n");
186 raw1394_destroy_handle(handle);
187 exit(1);
188 }
189
190 int nc = raw1394_get_nodecount(handle);
191 if (verbose)
192 printf ("%d nodes found.\n\n", nc);
193
194 for (i = nc - 1; i >= 0; i--) {
195 if (rom1394_get_directory(handle, i, &dir) < 0) {
196 if (verbose) fprintf(stderr,
197 "error reading config rom directory for node %d\n", i);
198 }
199
200 if (verbose)
201 printf("node %d: vendor_id = 0x%08x model_id = 0x%08x\n\n",
202 i, dir.vendor_id, dir.model_id);
203
204 if ( get_vendor (dir.vendor_id) &&
205 get_model (dir.model_id) ) {
206
207 if (dir.unit_spec_id != DCT6200_SPEC_ID)
208 fprintf(stderr, "Warning: Unit Spec ID different: 0x%08x\n",
209 dir.unit_spec_id);
210 if (dir.unit_sw_version != DCT6200_SW_VERSION)
211 fprintf(stderr, "Warning: Unit Software Version different: 0x%08x\n",
212 dir.unit_sw_version);
213 device = i;
214 break;
215 }
216 }
217
218 if (device == -1) {
219 fprintf(stderr,
220 "\nCould not find Motorola DCT-6200 on the 1394 bus.\n"
221 " Run with \"-v\". Then run with \"-V vendor_id -M model_id\""
222 ".\n--OR--\n"
223 " Run plugreport,then retry /w \"-p {Host Adapter #}\"\n\n");
224 raw1394_destroy_handle(handle);
225 exit(1);
226 }
227
228 if (chn > 0) {
229 if (verbose) printf("Changing to channel %d\n", chn);
230
231 dig[2] = (chn % 10);
232 dig[1] = (chn % 100) / 10;
233 dig[0] = (chn % 1000) / 100;
234
235 if (verbose)
236 printf("AV/C Command: %d%d%d = Op1=0x%08X Op2=0x%08X Op3=0x%08X\n",
237 dig[0], dig[1], dig[2],
238 CTL_CMD0 | dig[0], CTL_CMD0 | dig[1], CTL_CMD0 | dig[2]);
239
240 for (i=0; i<3; i++) {
241 cmd[0] = CTL_CMD0 | dig[i];
242 cmd[1] = 0x0;
243
244 avc1394_transaction_block(handle, device, cmd, 2, 1);
245 usleep(500000); // small delay for button to register
246 }
247 }
248 raw1394_destroy_handle(handle);
249 exit(0);
250}