~ubuntu-branches/ubuntu/natty/lirc/natty-proposed

« back to all changes in this revision

Viewing changes to daemons/hw_atwf83.c

  • Committer: Bazaar Package Importer
  • Author(s): Mario Limonciello
  • Date: 2010-04-02 15:06:19 UTC
  • mfrom: (1.2.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100402150619-y1z8c1yqv621a11o
Tags: 0.8.7~pre2-0ubuntu1
* Update to 0.8.7~pre2
  - Fixes issues with lirc on maverick. (LP: #620498)
* Add lirc-in-kernel-ioctls.patch to use ioctls from the kernel for drivers.
* Drop patches upstream now:
  - debian/patches/appleir_repeat_issue.patch
  - debian/patches/hauppauge-tv-card.patch
  - debian/patches/lirc-i2c-2.6.patch
  - debian/patches/lirc_dev-2.6.33.patch
* Add updated-driver-names.patch 
* Refresh patches:
  - debian/patches/02_Makefile.in
  - debian/patches/13-warning-cleanup
* Update extra transmitter and remote databases to not reference atiusb.
* debian/control:
  - Update branches to be owned by ~mythbuntu-dev
* Disable in-kernel-support when starting lircd, and re-enable when
  stopping.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
 ** hw_atwf83.c *************************************************************
 
3
 ****************************************************************************
 
4
 *
 
5
 * Lirc driver for Aureal remote (ATWF@83-W001 ESKY.CC USB_V3B)
 
6
 *
 
7
 * Copyright (C) 2010 Romain Henriet <romain-devel@laposte.net>
 
8
 *
 
9
 * Distribute under GPL version 2 or later.
 
10
 *
 
11
 */
 
12
 
 
13
#include <stdio.h>
 
14
#include <pthread.h>
 
15
#include <sys/fcntl.h>
 
16
#include <signal.h>
 
17
#include "hardware.h"
 
18
#include "ir_remote.h"
 
19
#include "lircd.h"
 
20
 
 
21
enum
 
22
{
 
23
        RPT_NO = 0,
 
24
        RPT_YES = 1,
 
25
};
 
26
 
 
27
static int atwf83_init();
 
28
static int atwf83_deinit();
 
29
static char *atwf83_rec(struct ir_remote *remotes);
 
30
static int atwf83_decode(struct ir_remote *remote,
 
31
                         ir_code *prep, ir_code *codep, ir_code *postp,
 
32
                         int *repeat_flagp,
 
33
                         lirc_t *min_remaining_gapp,
 
34
                         lirc_t *max_remaining_gapp);
 
35
static void* atwf83_repeat();
 
36
 
 
37
const unsigned release_code =0x00000000;
 
38
/** Time to wait before first repetition */
 
39
const unsigned repeat_time1_us = 500000;
 
40
/** Time to wait between two repetitions */
 
41
const unsigned repeat_time2_us = 100000;
 
42
/** Pipe between main thread and repetition thread */
 
43
static int fd_pipe[2] = {-1,-1};
 
44
/** Thread that simulates repetitions */
 
45
static pthread_t repeat_thread;
 
46
/** File descriptor for the real device */
 
47
static int fd_hidraw;
 
48
 
 
49
const int main_code_length = 32;
 
50
static signed int main_code = 0;
 
51
static struct timeval start,end,last;
 
52
static int repeat_state = RPT_NO;
 
53
 
 
54
/* Aureal USB iR Receiver */
 
55
struct hardware hw_atwf83=
 
56
{
 
57
        "/dev/hidraw0",         /* "device" */
 
58
        -1,                     /* fd (device) */
 
59
        LIRC_CAN_REC_LIRCCODE,  /* features */
 
60
        0,                      /* send_mode */
 
61
        LIRC_MODE_LIRCCODE,     /* rec_mode */
 
62
        32,                     /* code_length */
 
63
        atwf83_init,            /* init_func */
 
64
        atwf83_deinit,          /* deinit_func */
 
65
        NULL,                   /* send_func */
 
66
        atwf83_rec,             /* rec_func */
 
67
        atwf83_decode,          /* decode_func */
 
68
        NULL,                   /* ioctl_func */
 
69
        NULL,                   /* readdata */
 
70
        "atwf83"                /* name */
 
71
};
 
72
 
 
73
int atwf83_decode(struct ir_remote *remote,
 
74
                  ir_code *prep, ir_code *codep, ir_code *postp,
 
75
                  int *repeat_flagp,
 
76
                  lirc_t *min_remaining_gapp,
 
77
                  lirc_t *max_remaining_gapp)
 
78
{
 
79
        LOGPRINTF(1, "atwf83_decode");
 
80
 
 
81
        if(!map_code(remote,prep,codep,postp,0,0,
 
82
                     main_code_length,main_code,0,0))
 
83
        {
 
84
                return 0;
 
85
        }
 
86
 
 
87
        map_gap(remote, &start, &last, 0, repeat_flagp,
 
88
                min_remaining_gapp, max_remaining_gapp);
 
89
        /* override repeat */
 
90
        *repeat_flagp = repeat_state;
 
91
 
 
92
        return 1;
 
93
}
 
94
 
 
95
int atwf83_init()
 
96
{
 
97
        logprintf(LOG_INFO, "initializing '%s'", hw.device);
 
98
        if ((fd_hidraw = open(hw.device, O_RDONLY)) < 0)
 
99
        {
 
100
                logprintf(LOG_ERR, "unable to open '%s'", hw.device);
 
101
                return 0;
 
102
        }
 
103
        /* Create pipe so that events sent by the repeat thread will
 
104
           trigger main thread */
 
105
        if (pipe(fd_pipe) != 0)
 
106
        {
 
107
                logperror(LOG_ERR, "couldn't open pipe");
 
108
                close(fd_hidraw);
 
109
                return 0;
 
110
        }
 
111
        hw.fd = fd_pipe[0];
 
112
        /* Create thread to simulate repetitions */
 
113
        if (pthread_create(&repeat_thread, NULL, atwf83_repeat, NULL))
 
114
        {
 
115
                logprintf(LOG_ERR, "Could not create \"repeat thread\"");
 
116
                return 0;
 
117
        }
 
118
        return 1;
 
119
}
 
120
 
 
121
int atwf83_deinit()
 
122
{
 
123
        pthread_cancel(repeat_thread);
 
124
        if(fd_hidraw != -1)
 
125
        {
 
126
                logprintf(LOG_INFO, "closing '%s'", hw.device);
 
127
                close(fd_hidraw);
 
128
                fd_hidraw=-1;
 
129
        }
 
130
        if (fd_pipe[0] >= 0)
 
131
        {
 
132
                close(fd_pipe[0]);
 
133
                fd_pipe[0] = -1;
 
134
        }
 
135
        if (fd_pipe[1] >= 0)
 
136
        {
 
137
                close(fd_pipe[1]);
 
138
                fd_pipe[1] = -1;
 
139
        }
 
140
        hw.fd = -1;
 
141
        return 1;
 
142
}
 
143
 
 
144
/**
 
145
 *      Runtime that reads device, forwards codes to main thread
 
146
 *      and simulates repetitions.
 
147
 */
 
148
void* atwf83_repeat()
 
149
{
 
150
        unsigned ev[2];
 
151
        unsigned current_code;
 
152
        int rd, sel;
 
153
        fd_set files;
 
154
        struct timeval delay;
 
155
        int pressed=0;
 
156
        int fd = fd_pipe[1];
 
157
 
 
158
        while(1)
 
159
        {
 
160
                // Initialize set to monitor device's events
 
161
                FD_ZERO(&files);
 
162
                FD_SET(fd_hidraw, &files);
 
163
                if (pressed)
 
164
                {
 
165
                        sel = select(FD_SETSIZE, &files, NULL, NULL, &delay);
 
166
                }
 
167
                else
 
168
                {
 
169
                        sel = select(FD_SETSIZE, &files, NULL, NULL, NULL);
 
170
                }
 
171
 
 
172
                switch (sel)
 
173
                {
 
174
                case 1:
 
175
                        // Data ready in device's file
 
176
                        rd = read(fd_hidraw, ev, sizeof(ev));
 
177
                        if (rd==-1)
 
178
                        {
 
179
                                // Error
 
180
                                logprintf(LOG_ERR, "(%s) Could not read %s",
 
181
                                          __FUNCTION__, hw.device);
 
182
                                goto exit_loop;
 
183
                        }
 
184
                        if (rd < 7 ||
 
185
                            ev[1]!=0 ||
 
186
                            (rd==7 && ev[0]==0x200) ||
 
187
                            (rd==8 && ev[0]==0))
 
188
                        {
 
189
                                // Release code : stop repetitions
 
190
                                pressed = 0;
 
191
                                current_code = release_code;
 
192
                        }
 
193
                        else
 
194
                        {
 
195
                                // Key code : forward it to main thread
 
196
                                pressed = 1;
 
197
                                delay.tv_sec = 0;
 
198
                                delay.tv_usec = repeat_time1_us;
 
199
                                current_code = ev[0];
 
200
                        }
 
201
                        break;
 
202
                case 0:
 
203
                        // Timeout : send current_code again to main
 
204
                        //           thread to simulate repetition
 
205
                        delay.tv_sec = 0;
 
206
                        delay.tv_usec = repeat_time2_us;
 
207
                        break;
 
208
                default:
 
209
                        // Error
 
210
                        logprintf(LOG_ERR,"(%s) select() failed",
 
211
                                  __FUNCTION__);
 
212
                        goto exit_loop;
 
213
                }
 
214
                // Send code to main thread through pipe
 
215
                write(fd, &current_code, sizeof(current_code));
 
216
        }
 
217
 exit_loop:
 
218
        
 
219
        fd_pipe[1] = -1;
 
220
        close(fd);
 
221
        return NULL;
 
222
}
 
223
 
 
224
/*
 
225
*  Aureal Technology ATWF@83 cheap remote
 
226
*  specific code.
 
227
*/
 
228
 
 
229
char *atwf83_rec(struct ir_remote *remotes)
 
230
{
 
231
        unsigned ev;
 
232
        int rd;
 
233
        last = end;
 
234
        gettimeofday(&start,NULL);
 
235
        rd = read(hw.fd, &ev, sizeof(ev));
 
236
 
 
237
        if (rd==-1)
 
238
        {
 
239
                // Error
 
240
                logprintf(LOG_ERR,"(%s) could not read pipe", __FUNCTION__);
 
241
                atwf83_deinit();
 
242
                return 0;
 
243
        }
 
244
 
 
245
        if (ev == 0)
 
246
        {
 
247
                // Release code
 
248
                main_code = 0;
 
249
                return 0;
 
250
        }
 
251
 
 
252
        LOGPRINTF(1, "atwf83 : %x", ev);
 
253
        // Record the code and check for repetition
 
254
        if (main_code == ev)
 
255
        {
 
256
                repeat_state = RPT_YES;
 
257
        }
 
258
        else
 
259
        {
 
260
                main_code = ev;
 
261
                repeat_state = RPT_NO;
 
262
        }
 
263
        gettimeofday(&end,NULL);
 
264
        return decode_all(remotes);
 
265
}