• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $Id: rds-saa6588.c,v 1.3 2005/06/12 04:19:19 mchehab Exp $
3  *
4  * poll i2c RDS receiver [Philips saa6588]
5  *
6  */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <errno.h>
13 #include <sys/ioctl.h>
14 #include <linux/types.h>
15 #include <linux/i2c.h>
16 #include <linux/i2c-dev.h>
17 
18 int debug;
19 
20 /* ----------------------------------------------------------------- */
21 
22 char rds_psn[9];
23 char rds_txt[65];
24 
rds_decode(int blkno,int b1,int b2)25 static void rds_decode(int blkno,int b1, int b2)
26 {
27     static int group,spare,c1,c2;
28 
29     switch (blkno) {
30     case 0:
31 	if (debug)
32 	    fprintf(stderr,"block A - id=%d\n",
33 		    (b1 << 8) | b2);
34 	break;
35     case 1:
36 	if (debug)
37 	    fprintf(stderr,"block B - group=%d%c tp=%d pty=%d spare=%d\n",
38 		    (b1 >> 4) & 0x0f,
39 		    ((b1 >> 3) & 0x01) + 'A',
40 		    (b1 >> 2) & 0x01,
41 		    ((b1 << 3) & 0x18) | ((b2 >> 5) & 0x07),
42 		    b2 & 0x1f);
43 	group = (b1 >> 3) & 0x1f;
44 	spare = b2 & 0x1f;
45 	break;
46     case 2:
47 	if (debug)
48 	    fprintf(stderr,"block C - 0x%02x 0x%02x\n",b1,b2);
49 	c1 = b1;
50 	c2 = b2;
51 	break;
52     case 3:
53 	if (debug)
54 	    fprintf(stderr,"block D - 0x%02x 0x%02x\n",b1,b2);
55 	switch (group) {
56 	case 0:
57 	    rds_psn[2*(spare & 0x03)+0] = b1;
58 	    rds_psn[2*(spare & 0x03)+1] = b2;
59 	    if ((spare & 0x03) == 0x03)
60 		fprintf(stderr,"PSN #>%s<#\n",rds_psn);
61 	    break;
62 	case 4:
63 	    rds_txt[4*(spare & 0x0f)+0] = c1;
64 	    rds_txt[4*(spare & 0x0f)+1] = c2;
65 	    rds_txt[4*(spare & 0x0f)+2] = b1;
66 	    rds_txt[4*(spare & 0x0f)+3] = b2;
67 	    if ((spare & 0x0f) == 0x0f)
68 		fprintf(stderr,"TXT #>%s<#\n",rds_txt);
69 	    break;
70 	}
71 	break;
72     default:
73 	fprintf(stderr,"unknown block [%d]\n",blkno);
74     }
75 }
76 
77 int
main(int argc,char * argv[])78 main(int argc, char *argv[])
79 {
80     int  c,f,rc, no, lastno = -1;
81     unsigned char b[40];
82     char *device = "/dev/i2c-0";
83 
84     /* parse options */
85     while (-1 != (c=getopt(argc,argv,"hvd:"))) {
86 	switch (c){
87 	case 'd':
88 	    if (optarg)
89 		device = optarg;
90 	    break;
91 	case 'v':
92 	    debug = 1;
93 	    break;
94 	case 'h':
95 	default:
96 	    printf("poll i2c RDS receiver [saa6588] via chardev\n");
97 	    printf("usage: %s [ -d i2c-device ]\n",argv[0]);
98 	    exit(1);
99 	}
100     }
101 
102     if (-1 == (f = open(device,O_RDWR))) {
103 	fprintf(stderr,"open %s: %s\n",device,strerror(errno));
104 	exit(1);
105     }
106     ioctl(f,I2C_SLAVE,0x20 >> 1);
107     for (;;) {
108 	memset(b,0,sizeof(b));
109 	rc = read(f,b,6);
110 	if (6 != rc) {
111 	    fprintf(stderr,"oops: read: rc=%d, expected 6 [%s]\n",
112 		    rc,strerror(errno));
113 	    break;
114 	}
115 	if (0 == (b[0] & 0x10)) {
116 	    fprintf(stderr,"no signal\r");
117 	    continue;
118 	}
119 	if (b[0] & 0x08) {
120 	    fprintf(stderr,"overflow detected\n");
121 	}
122 	if (b[0] & 0x04) {
123 	    fprintf(stderr,"reset detected\n");
124 	}
125 	if (debug)
126 	    fprintf(stderr,"raw: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
127 		    b[0],b[1],b[2],b[3],b[4],b[5]);
128 	no = b[0] >> 5;
129 	if (lastno != no) {
130 		rds_decode(no, b[1], b[2]);
131 		lastno = no;
132 	}
133 	usleep(10*1000);
134     }
135     close(f);
136     exit(0);
137 }
138