Ticket #235: 6200ch.c

File 6200ch.c, 6.7 KB (added by Mike Cannon <m_cannon@…>, 19 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}