diff options
author | Andy Walls <awalls@md.metrocast.net> | 2011-01-13 00:00:33 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-01-19 08:46:04 -0500 |
commit | 06da95a3ec831dee23f6af58934944a8eb9c3a56 (patch) | |
tree | f7a53819f5942ced2907596f5208b11734929f4c | |
parent | 02fcaaa3a52b2bdad8a08a3ee5747f27f27df27d (diff) |
[media] lirc_zilog: Split struct IR into structs IR, IR_tx, and IR_rx
This change is a mostly mechanical break of the main struct IR
data structure into common, Rx, and Tx structures. There were some
small logical changes required as well, such as eliminating "is_hdpvr",
to accomplish this.
This change is an intiial step in reworking lirc_zilog to decouple the
Rx and Tx handling as much as possible to fit with the new I2C
binding model. This change actually makes lirc_zilog a little more
broken than it already was - memory deallocation in particular got worse.
However, this change makes the remaining problems easier to see and address.
Signed-off-by: Andy Walls <awalls@md.metrocast.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/staging/lirc/lirc_zilog.c | 298 |
1 files changed, 171 insertions, 127 deletions
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c index 91125336144e..85e312f33513 100644 --- a/drivers/staging/lirc/lirc_zilog.c +++ b/drivers/staging/lirc/lirc_zilog.c | |||
@@ -60,17 +60,9 @@ | |||
60 | #include <media/lirc_dev.h> | 60 | #include <media/lirc_dev.h> |
61 | #include <media/lirc.h> | 61 | #include <media/lirc.h> |
62 | 62 | ||
63 | struct IR { | 63 | struct IR_rx { |
64 | struct lirc_driver l; | ||
65 | |||
66 | /* Device info */ | ||
67 | struct mutex ir_lock; | ||
68 | int open; | ||
69 | bool is_hdpvr; | ||
70 | |||
71 | /* RX device */ | 64 | /* RX device */ |
72 | struct i2c_client c_rx; | 65 | struct i2c_client c_rx; |
73 | int have_rx; | ||
74 | 66 | ||
75 | /* RX device buffer & lock */ | 67 | /* RX device buffer & lock */ |
76 | struct lirc_buffer buf; | 68 | struct lirc_buffer buf; |
@@ -84,11 +76,26 @@ struct IR { | |||
84 | 76 | ||
85 | /* RX read data */ | 77 | /* RX read data */ |
86 | unsigned char b[3]; | 78 | unsigned char b[3]; |
79 | bool hdpvr_data_fmt; | ||
80 | }; | ||
87 | 81 | ||
82 | struct IR_tx { | ||
88 | /* TX device */ | 83 | /* TX device */ |
89 | struct i2c_client c_tx; | 84 | struct i2c_client c_tx; |
85 | |||
86 | /* TX additional actions needed */ | ||
90 | int need_boot; | 87 | int need_boot; |
91 | int have_tx; | 88 | bool post_tx_ready_poll; |
89 | }; | ||
90 | |||
91 | struct IR { | ||
92 | struct lirc_driver l; | ||
93 | |||
94 | struct mutex ir_lock; | ||
95 | int open; | ||
96 | |||
97 | struct IR_rx *rx; | ||
98 | struct IR_tx *tx; | ||
92 | }; | 99 | }; |
93 | 100 | ||
94 | /* Minor -> data mapping */ | 101 | /* Minor -> data mapping */ |
@@ -149,8 +156,12 @@ static int add_to_buf(struct IR *ir) | |||
149 | int ret; | 156 | int ret; |
150 | int failures = 0; | 157 | int failures = 0; |
151 | unsigned char sendbuf[1] = { 0 }; | 158 | unsigned char sendbuf[1] = { 0 }; |
159 | struct IR_rx *rx = ir->rx; | ||
152 | 160 | ||
153 | if (lirc_buffer_full(&ir->buf)) { | 161 | if (rx == NULL) |
162 | return -ENXIO; | ||
163 | |||
164 | if (lirc_buffer_full(&rx->buf)) { | ||
154 | dprintk("buffer overflow\n"); | 165 | dprintk("buffer overflow\n"); |
155 | return -EOVERFLOW; | 166 | return -EOVERFLOW; |
156 | } | 167 | } |
@@ -170,7 +181,7 @@ static int add_to_buf(struct IR *ir) | |||
170 | * Send random "poll command" (?) Windows driver does this | 181 | * Send random "poll command" (?) Windows driver does this |
171 | * and it is a good point to detect chip failure. | 182 | * and it is a good point to detect chip failure. |
172 | */ | 183 | */ |
173 | ret = i2c_master_send(&ir->c_rx, sendbuf, 1); | 184 | ret = i2c_master_send(&rx->c_rx, sendbuf, 1); |
174 | if (ret != 1) { | 185 | if (ret != 1) { |
175 | zilog_error("i2c_master_send failed with %d\n", ret); | 186 | zilog_error("i2c_master_send failed with %d\n", ret); |
176 | if (failures >= 3) { | 187 | if (failures >= 3) { |
@@ -186,44 +197,45 @@ static int add_to_buf(struct IR *ir) | |||
186 | 197 | ||
187 | set_current_state(TASK_UNINTERRUPTIBLE); | 198 | set_current_state(TASK_UNINTERRUPTIBLE); |
188 | schedule_timeout((100 * HZ + 999) / 1000); | 199 | schedule_timeout((100 * HZ + 999) / 1000); |
189 | ir->need_boot = 1; | 200 | if (ir->tx != NULL) |
201 | ir->tx->need_boot = 1; | ||
190 | 202 | ||
191 | ++failures; | 203 | ++failures; |
192 | mutex_unlock(&ir->ir_lock); | 204 | mutex_unlock(&ir->ir_lock); |
193 | continue; | 205 | continue; |
194 | } | 206 | } |
195 | 207 | ||
196 | ret = i2c_master_recv(&ir->c_rx, keybuf, sizeof(keybuf)); | 208 | ret = i2c_master_recv(&rx->c_rx, keybuf, sizeof(keybuf)); |
197 | mutex_unlock(&ir->ir_lock); | 209 | mutex_unlock(&ir->ir_lock); |
198 | if (ret != sizeof(keybuf)) { | 210 | if (ret != sizeof(keybuf)) { |
199 | zilog_error("i2c_master_recv failed with %d -- " | 211 | zilog_error("i2c_master_recv failed with %d -- " |
200 | "keeping last read buffer\n", ret); | 212 | "keeping last read buffer\n", ret); |
201 | } else { | 213 | } else { |
202 | ir->b[0] = keybuf[3]; | 214 | rx->b[0] = keybuf[3]; |
203 | ir->b[1] = keybuf[4]; | 215 | rx->b[1] = keybuf[4]; |
204 | ir->b[2] = keybuf[5]; | 216 | rx->b[2] = keybuf[5]; |
205 | dprintk("key (0x%02x/0x%02x)\n", ir->b[0], ir->b[1]); | 217 | dprintk("key (0x%02x/0x%02x)\n", rx->b[0], rx->b[1]); |
206 | } | 218 | } |
207 | 219 | ||
208 | /* key pressed ? */ | 220 | /* key pressed ? */ |
209 | if (ir->is_hdpvr) { | 221 | if (rx->hdpvr_data_fmt) { |
210 | if (got_data && (keybuf[0] == 0x80)) | 222 | if (got_data && (keybuf[0] == 0x80)) |
211 | return 0; | 223 | return 0; |
212 | else if (got_data && (keybuf[0] == 0x00)) | 224 | else if (got_data && (keybuf[0] == 0x00)) |
213 | return -ENODATA; | 225 | return -ENODATA; |
214 | } else if ((ir->b[0] & 0x80) == 0) | 226 | } else if ((rx->b[0] & 0x80) == 0) |
215 | return got_data ? 0 : -ENODATA; | 227 | return got_data ? 0 : -ENODATA; |
216 | 228 | ||
217 | /* look what we have */ | 229 | /* look what we have */ |
218 | code = (((__u16)ir->b[0] & 0x7f) << 6) | (ir->b[1] >> 2); | 230 | code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2); |
219 | 231 | ||
220 | codes[0] = (code >> 8) & 0xff; | 232 | codes[0] = (code >> 8) & 0xff; |
221 | codes[1] = code & 0xff; | 233 | codes[1] = code & 0xff; |
222 | 234 | ||
223 | /* return it */ | 235 | /* return it */ |
224 | lirc_buffer_write(&ir->buf, codes); | 236 | lirc_buffer_write(&rx->buf, codes); |
225 | ++got_data; | 237 | ++got_data; |
226 | } while (!lirc_buffer_full(&ir->buf)); | 238 | } while (!lirc_buffer_full(&rx->buf)); |
227 | 239 | ||
228 | return 0; | 240 | return 0; |
229 | } | 241 | } |
@@ -241,9 +253,13 @@ static int add_to_buf(struct IR *ir) | |||
241 | static int lirc_thread(void *arg) | 253 | static int lirc_thread(void *arg) |
242 | { | 254 | { |
243 | struct IR *ir = arg; | 255 | struct IR *ir = arg; |
256 | struct IR_rx *rx = ir->rx; | ||
257 | |||
258 | if (rx == NULL) | ||
259 | return -ENXIO; | ||
244 | 260 | ||
245 | if (ir->t_notify != NULL) | 261 | if (rx->t_notify != NULL) |
246 | complete(ir->t_notify); | 262 | complete(rx->t_notify); |
247 | 263 | ||
248 | dprintk("poll thread started\n"); | 264 | dprintk("poll thread started\n"); |
249 | 265 | ||
@@ -264,23 +280,23 @@ static int lirc_thread(void *arg) | |||
264 | * lost keypresses. | 280 | * lost keypresses. |
265 | */ | 281 | */ |
266 | schedule_timeout((260 * HZ) / 1000); | 282 | schedule_timeout((260 * HZ) / 1000); |
267 | if (ir->shutdown) | 283 | if (rx->shutdown) |
268 | break; | 284 | break; |
269 | if (!add_to_buf(ir)) | 285 | if (!add_to_buf(ir)) |
270 | wake_up_interruptible(&ir->buf.wait_poll); | 286 | wake_up_interruptible(&rx->buf.wait_poll); |
271 | } else { | 287 | } else { |
272 | /* if device not opened so we can sleep half a second */ | 288 | /* if device not opened so we can sleep half a second */ |
273 | set_current_state(TASK_INTERRUPTIBLE); | 289 | set_current_state(TASK_INTERRUPTIBLE); |
274 | schedule_timeout(HZ/2); | 290 | schedule_timeout(HZ/2); |
275 | } | 291 | } |
276 | } while (!ir->shutdown); | 292 | } while (!rx->shutdown); |
277 | 293 | ||
278 | if (ir->t_notify2 != NULL) | 294 | if (rx->t_notify2 != NULL) |
279 | wait_for_completion(ir->t_notify2); | 295 | wait_for_completion(rx->t_notify2); |
280 | 296 | ||
281 | ir->task = NULL; | 297 | rx->task = NULL; |
282 | if (ir->t_notify != NULL) | 298 | if (rx->t_notify != NULL) |
283 | complete(ir->t_notify); | 299 | complete(rx->t_notify); |
284 | 300 | ||
285 | dprintk("poll thread ended\n"); | 301 | dprintk("poll thread ended\n"); |
286 | return 0; | 302 | return 0; |
@@ -298,10 +314,10 @@ static int set_use_inc(void *data) | |||
298 | * this is completely broken code. lirc_unregister_driver() | 314 | * this is completely broken code. lirc_unregister_driver() |
299 | * must be possible even when the device is open | 315 | * must be possible even when the device is open |
300 | */ | 316 | */ |
301 | if (ir->c_rx.addr) | 317 | if (ir->rx != NULL) |
302 | i2c_use_client(&ir->c_rx); | 318 | i2c_use_client(&ir->rx->c_rx); |
303 | if (ir->c_tx.addr) | 319 | if (ir->tx != NULL) |
304 | i2c_use_client(&ir->c_tx); | 320 | i2c_use_client(&ir->tx->c_tx); |
305 | 321 | ||
306 | return 0; | 322 | return 0; |
307 | } | 323 | } |
@@ -310,10 +326,10 @@ static void set_use_dec(void *data) | |||
310 | { | 326 | { |
311 | struct IR *ir = data; | 327 | struct IR *ir = data; |
312 | 328 | ||
313 | if (ir->c_rx.addr) | 329 | if (ir->rx) |
314 | i2c_release_client(&ir->c_rx); | 330 | i2c_release_client(&ir->rx->c_rx); |
315 | if (ir->c_tx.addr) | 331 | if (ir->tx) |
316 | i2c_release_client(&ir->c_tx); | 332 | i2c_release_client(&ir->tx->c_tx); |
317 | if (ir->l.owner != NULL) | 333 | if (ir->l.owner != NULL) |
318 | module_put(ir->l.owner); | 334 | module_put(ir->l.owner); |
319 | } | 335 | } |
@@ -452,7 +468,7 @@ corrupt: | |||
452 | } | 468 | } |
453 | 469 | ||
454 | /* send a block of data to the IR TX device */ | 470 | /* send a block of data to the IR TX device */ |
455 | static int send_data_block(struct IR *ir, unsigned char *data_block) | 471 | static int send_data_block(struct IR_tx *tx, unsigned char *data_block) |
456 | { | 472 | { |
457 | int i, j, ret; | 473 | int i, j, ret; |
458 | unsigned char buf[5]; | 474 | unsigned char buf[5]; |
@@ -466,7 +482,7 @@ static int send_data_block(struct IR *ir, unsigned char *data_block) | |||
466 | buf[1 + j] = data_block[i + j]; | 482 | buf[1 + j] = data_block[i + j]; |
467 | dprintk("%02x %02x %02x %02x %02x", | 483 | dprintk("%02x %02x %02x %02x %02x", |
468 | buf[0], buf[1], buf[2], buf[3], buf[4]); | 484 | buf[0], buf[1], buf[2], buf[3], buf[4]); |
469 | ret = i2c_master_send(&ir->c_tx, buf, tosend + 1); | 485 | ret = i2c_master_send(&tx->c_tx, buf, tosend + 1); |
470 | if (ret != tosend + 1) { | 486 | if (ret != tosend + 1) { |
471 | zilog_error("i2c_master_send failed with %d\n", ret); | 487 | zilog_error("i2c_master_send failed with %d\n", ret); |
472 | return ret < 0 ? ret : -EFAULT; | 488 | return ret < 0 ? ret : -EFAULT; |
@@ -477,32 +493,32 @@ static int send_data_block(struct IR *ir, unsigned char *data_block) | |||
477 | } | 493 | } |
478 | 494 | ||
479 | /* send boot data to the IR TX device */ | 495 | /* send boot data to the IR TX device */ |
480 | static int send_boot_data(struct IR *ir) | 496 | static int send_boot_data(struct IR_tx *tx) |
481 | { | 497 | { |
482 | int ret; | 498 | int ret; |
483 | unsigned char buf[4]; | 499 | unsigned char buf[4]; |
484 | 500 | ||
485 | /* send the boot block */ | 501 | /* send the boot block */ |
486 | ret = send_data_block(ir, tx_data->boot_data); | 502 | ret = send_data_block(tx, tx_data->boot_data); |
487 | if (ret != 0) | 503 | if (ret != 0) |
488 | return ret; | 504 | return ret; |
489 | 505 | ||
490 | /* kick it off? */ | 506 | /* kick it off? */ |
491 | buf[0] = 0x00; | 507 | buf[0] = 0x00; |
492 | buf[1] = 0x20; | 508 | buf[1] = 0x20; |
493 | ret = i2c_master_send(&ir->c_tx, buf, 2); | 509 | ret = i2c_master_send(&tx->c_tx, buf, 2); |
494 | if (ret != 2) { | 510 | if (ret != 2) { |
495 | zilog_error("i2c_master_send failed with %d\n", ret); | 511 | zilog_error("i2c_master_send failed with %d\n", ret); |
496 | return ret < 0 ? ret : -EFAULT; | 512 | return ret < 0 ? ret : -EFAULT; |
497 | } | 513 | } |
498 | ret = i2c_master_send(&ir->c_tx, buf, 1); | 514 | ret = i2c_master_send(&tx->c_tx, buf, 1); |
499 | if (ret != 1) { | 515 | if (ret != 1) { |
500 | zilog_error("i2c_master_send failed with %d\n", ret); | 516 | zilog_error("i2c_master_send failed with %d\n", ret); |
501 | return ret < 0 ? ret : -EFAULT; | 517 | return ret < 0 ? ret : -EFAULT; |
502 | } | 518 | } |
503 | 519 | ||
504 | /* Here comes the firmware version... (hopefully) */ | 520 | /* Here comes the firmware version... (hopefully) */ |
505 | ret = i2c_master_recv(&ir->c_tx, buf, 4); | 521 | ret = i2c_master_recv(&tx->c_tx, buf, 4); |
506 | if (ret != 4) { | 522 | if (ret != 4) { |
507 | zilog_error("i2c_master_recv failed with %d\n", ret); | 523 | zilog_error("i2c_master_recv failed with %d\n", ret); |
508 | return 0; | 524 | return 0; |
@@ -542,7 +558,7 @@ static void fw_unload(void) | |||
542 | } | 558 | } |
543 | 559 | ||
544 | /* load "firmware" for the IR TX device */ | 560 | /* load "firmware" for the IR TX device */ |
545 | static int fw_load(struct IR *ir) | 561 | static int fw_load(struct IR_tx *tx) |
546 | { | 562 | { |
547 | int ret; | 563 | int ret; |
548 | unsigned int i; | 564 | unsigned int i; |
@@ -557,7 +573,7 @@ static int fw_load(struct IR *ir) | |||
557 | } | 573 | } |
558 | 574 | ||
559 | /* Request codeset data file */ | 575 | /* Request codeset data file */ |
560 | ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &ir->c_tx.dev); | 576 | ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &tx->c_tx.dev); |
561 | if (ret != 0) { | 577 | if (ret != 0) { |
562 | zilog_error("firmware haup-ir-blaster.bin not available " | 578 | zilog_error("firmware haup-ir-blaster.bin not available " |
563 | "(%d)\n", ret); | 579 | "(%d)\n", ret); |
@@ -684,20 +700,20 @@ out: | |||
684 | } | 700 | } |
685 | 701 | ||
686 | /* initialise the IR TX device */ | 702 | /* initialise the IR TX device */ |
687 | static int tx_init(struct IR *ir) | 703 | static int tx_init(struct IR_tx *tx) |
688 | { | 704 | { |
689 | int ret; | 705 | int ret; |
690 | 706 | ||
691 | /* Load 'firmware' */ | 707 | /* Load 'firmware' */ |
692 | ret = fw_load(ir); | 708 | ret = fw_load(tx); |
693 | if (ret != 0) | 709 | if (ret != 0) |
694 | return ret; | 710 | return ret; |
695 | 711 | ||
696 | /* Send boot block */ | 712 | /* Send boot block */ |
697 | ret = send_boot_data(ir); | 713 | ret = send_boot_data(tx); |
698 | if (ret != 0) | 714 | if (ret != 0) |
699 | return ret; | 715 | return ret; |
700 | ir->need_boot = 0; | 716 | tx->need_boot = 0; |
701 | 717 | ||
702 | /* Looks good */ | 718 | /* Looks good */ |
703 | return 0; | 719 | return 0; |
@@ -713,20 +729,20 @@ static loff_t lseek(struct file *filep, loff_t offset, int orig) | |||
713 | static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) | 729 | static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) |
714 | { | 730 | { |
715 | struct IR *ir = filep->private_data; | 731 | struct IR *ir = filep->private_data; |
716 | unsigned char buf[ir->buf.chunk_size]; | 732 | struct IR_rx *rx = ir->rx; |
717 | int ret = 0, written = 0; | 733 | int ret = 0, written = 0; |
718 | DECLARE_WAITQUEUE(wait, current); | 734 | DECLARE_WAITQUEUE(wait, current); |
719 | 735 | ||
720 | dprintk("read called\n"); | 736 | dprintk("read called\n"); |
721 | if (ir->c_rx.addr == 0) | 737 | if (rx == NULL) |
722 | return -ENODEV; | 738 | return -ENODEV; |
723 | 739 | ||
724 | if (mutex_lock_interruptible(&ir->buf_lock)) | 740 | if (mutex_lock_interruptible(&rx->buf_lock)) |
725 | return -ERESTARTSYS; | 741 | return -ERESTARTSYS; |
726 | 742 | ||
727 | if (n % ir->buf.chunk_size) { | 743 | if (n % rx->buf.chunk_size) { |
728 | dprintk("read result = -EINVAL\n"); | 744 | dprintk("read result = -EINVAL\n"); |
729 | mutex_unlock(&ir->buf_lock); | 745 | mutex_unlock(&rx->buf_lock); |
730 | return -EINVAL; | 746 | return -EINVAL; |
731 | } | 747 | } |
732 | 748 | ||
@@ -735,7 +751,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) | |||
735 | * to avoid losing scan code (in case when queue is awaken somewhere | 751 | * to avoid losing scan code (in case when queue is awaken somewhere |
736 | * between while condition checking and scheduling) | 752 | * between while condition checking and scheduling) |
737 | */ | 753 | */ |
738 | add_wait_queue(&ir->buf.wait_poll, &wait); | 754 | add_wait_queue(&rx->buf.wait_poll, &wait); |
739 | set_current_state(TASK_INTERRUPTIBLE); | 755 | set_current_state(TASK_INTERRUPTIBLE); |
740 | 756 | ||
741 | /* | 757 | /* |
@@ -743,7 +759,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) | |||
743 | * mode and 'copy_to_user' is happy, wait for data. | 759 | * mode and 'copy_to_user' is happy, wait for data. |
744 | */ | 760 | */ |
745 | while (written < n && ret == 0) { | 761 | while (written < n && ret == 0) { |
746 | if (lirc_buffer_empty(&ir->buf)) { | 762 | if (lirc_buffer_empty(&rx->buf)) { |
747 | /* | 763 | /* |
748 | * According to the read(2) man page, 'written' can be | 764 | * According to the read(2) man page, 'written' can be |
749 | * returned as less than 'n', instead of blocking | 765 | * returned as less than 'n', instead of blocking |
@@ -763,16 +779,17 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) | |||
763 | schedule(); | 779 | schedule(); |
764 | set_current_state(TASK_INTERRUPTIBLE); | 780 | set_current_state(TASK_INTERRUPTIBLE); |
765 | } else { | 781 | } else { |
766 | lirc_buffer_read(&ir->buf, buf); | 782 | unsigned char buf[rx->buf.chunk_size]; |
783 | lirc_buffer_read(&rx->buf, buf); | ||
767 | ret = copy_to_user((void *)outbuf+written, buf, | 784 | ret = copy_to_user((void *)outbuf+written, buf, |
768 | ir->buf.chunk_size); | 785 | rx->buf.chunk_size); |
769 | written += ir->buf.chunk_size; | 786 | written += rx->buf.chunk_size; |
770 | } | 787 | } |
771 | } | 788 | } |
772 | 789 | ||
773 | remove_wait_queue(&ir->buf.wait_poll, &wait); | 790 | remove_wait_queue(&rx->buf.wait_poll, &wait); |
774 | set_current_state(TASK_RUNNING); | 791 | set_current_state(TASK_RUNNING); |
775 | mutex_unlock(&ir->buf_lock); | 792 | mutex_unlock(&rx->buf_lock); |
776 | 793 | ||
777 | dprintk("read result = %s (%d)\n", | 794 | dprintk("read result = %s (%d)\n", |
778 | ret ? "-EFAULT" : "OK", ret); | 795 | ret ? "-EFAULT" : "OK", ret); |
@@ -781,7 +798,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) | |||
781 | } | 798 | } |
782 | 799 | ||
783 | /* send a keypress to the IR TX device */ | 800 | /* send a keypress to the IR TX device */ |
784 | static int send_code(struct IR *ir, unsigned int code, unsigned int key) | 801 | static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) |
785 | { | 802 | { |
786 | unsigned char data_block[TX_BLOCK_SIZE]; | 803 | unsigned char data_block[TX_BLOCK_SIZE]; |
787 | unsigned char buf[2]; | 804 | unsigned char buf[2]; |
@@ -798,26 +815,26 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) | |||
798 | return ret; | 815 | return ret; |
799 | 816 | ||
800 | /* Send the data block */ | 817 | /* Send the data block */ |
801 | ret = send_data_block(ir, data_block); | 818 | ret = send_data_block(tx, data_block); |
802 | if (ret != 0) | 819 | if (ret != 0) |
803 | return ret; | 820 | return ret; |
804 | 821 | ||
805 | /* Send data block length? */ | 822 | /* Send data block length? */ |
806 | buf[0] = 0x00; | 823 | buf[0] = 0x00; |
807 | buf[1] = 0x40; | 824 | buf[1] = 0x40; |
808 | ret = i2c_master_send(&ir->c_tx, buf, 2); | 825 | ret = i2c_master_send(&tx->c_tx, buf, 2); |
809 | if (ret != 2) { | 826 | if (ret != 2) { |
810 | zilog_error("i2c_master_send failed with %d\n", ret); | 827 | zilog_error("i2c_master_send failed with %d\n", ret); |
811 | return ret < 0 ? ret : -EFAULT; | 828 | return ret < 0 ? ret : -EFAULT; |
812 | } | 829 | } |
813 | ret = i2c_master_send(&ir->c_tx, buf, 1); | 830 | ret = i2c_master_send(&tx->c_tx, buf, 1); |
814 | if (ret != 1) { | 831 | if (ret != 1) { |
815 | zilog_error("i2c_master_send failed with %d\n", ret); | 832 | zilog_error("i2c_master_send failed with %d\n", ret); |
816 | return ret < 0 ? ret : -EFAULT; | 833 | return ret < 0 ? ret : -EFAULT; |
817 | } | 834 | } |
818 | 835 | ||
819 | /* Send finished download? */ | 836 | /* Send finished download? */ |
820 | ret = i2c_master_recv(&ir->c_tx, buf, 1); | 837 | ret = i2c_master_recv(&tx->c_tx, buf, 1); |
821 | if (ret != 1) { | 838 | if (ret != 1) { |
822 | zilog_error("i2c_master_recv failed with %d\n", ret); | 839 | zilog_error("i2c_master_recv failed with %d\n", ret); |
823 | return ret < 0 ? ret : -EFAULT; | 840 | return ret < 0 ? ret : -EFAULT; |
@@ -831,7 +848,7 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) | |||
831 | /* Send prepare command? */ | 848 | /* Send prepare command? */ |
832 | buf[0] = 0x00; | 849 | buf[0] = 0x00; |
833 | buf[1] = 0x80; | 850 | buf[1] = 0x80; |
834 | ret = i2c_master_send(&ir->c_tx, buf, 2); | 851 | ret = i2c_master_send(&tx->c_tx, buf, 2); |
835 | if (ret != 2) { | 852 | if (ret != 2) { |
836 | zilog_error("i2c_master_send failed with %d\n", ret); | 853 | zilog_error("i2c_master_send failed with %d\n", ret); |
837 | return ret < 0 ? ret : -EFAULT; | 854 | return ret < 0 ? ret : -EFAULT; |
@@ -842,7 +859,7 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) | |||
842 | * last i2c_master_recv always fails with a -5, so for now, we're | 859 | * last i2c_master_recv always fails with a -5, so for now, we're |
843 | * going to skip this whole mess and say we're done on the HD PVR | 860 | * going to skip this whole mess and say we're done on the HD PVR |
844 | */ | 861 | */ |
845 | if (ir->is_hdpvr) { | 862 | if (!tx->post_tx_ready_poll) { |
846 | dprintk("sent code %u, key %u\n", code, key); | 863 | dprintk("sent code %u, key %u\n", code, key); |
847 | return 0; | 864 | return 0; |
848 | } | 865 | } |
@@ -856,7 +873,7 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) | |||
856 | for (i = 0; i < 20; ++i) { | 873 | for (i = 0; i < 20; ++i) { |
857 | set_current_state(TASK_UNINTERRUPTIBLE); | 874 | set_current_state(TASK_UNINTERRUPTIBLE); |
858 | schedule_timeout((50 * HZ + 999) / 1000); | 875 | schedule_timeout((50 * HZ + 999) / 1000); |
859 | ret = i2c_master_send(&ir->c_tx, buf, 1); | 876 | ret = i2c_master_send(&tx->c_tx, buf, 1); |
860 | if (ret == 1) | 877 | if (ret == 1) |
861 | break; | 878 | break; |
862 | dprintk("NAK expected: i2c_master_send " | 879 | dprintk("NAK expected: i2c_master_send " |
@@ -869,7 +886,7 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) | |||
869 | } | 886 | } |
870 | 887 | ||
871 | /* Seems to be an 'ok' response */ | 888 | /* Seems to be an 'ok' response */ |
872 | i = i2c_master_recv(&ir->c_tx, buf, 1); | 889 | i = i2c_master_recv(&tx->c_tx, buf, 1); |
873 | if (i != 1) { | 890 | if (i != 1) { |
874 | zilog_error("i2c_master_recv failed with %d\n", ret); | 891 | zilog_error("i2c_master_recv failed with %d\n", ret); |
875 | return -EFAULT; | 892 | return -EFAULT; |
@@ -894,10 +911,11 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, | |||
894 | loff_t *ppos) | 911 | loff_t *ppos) |
895 | { | 912 | { |
896 | struct IR *ir = filep->private_data; | 913 | struct IR *ir = filep->private_data; |
914 | struct IR_tx *tx = ir->tx; | ||
897 | size_t i; | 915 | size_t i; |
898 | int failures = 0; | 916 | int failures = 0; |
899 | 917 | ||
900 | if (ir->c_tx.addr == 0) | 918 | if (tx == NULL) |
901 | return -ENODEV; | 919 | return -ENODEV; |
902 | 920 | ||
903 | /* Validate user parameters */ | 921 | /* Validate user parameters */ |
@@ -918,15 +936,15 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, | |||
918 | } | 936 | } |
919 | 937 | ||
920 | /* Send boot data first if required */ | 938 | /* Send boot data first if required */ |
921 | if (ir->need_boot == 1) { | 939 | if (tx->need_boot == 1) { |
922 | ret = send_boot_data(ir); | 940 | ret = send_boot_data(tx); |
923 | if (ret == 0) | 941 | if (ret == 0) |
924 | ir->need_boot = 0; | 942 | tx->need_boot = 0; |
925 | } | 943 | } |
926 | 944 | ||
927 | /* Send the code */ | 945 | /* Send the code */ |
928 | if (ret == 0) { | 946 | if (ret == 0) { |
929 | ret = send_code(ir, (unsigned)command >> 16, | 947 | ret = send_code(tx, (unsigned)command >> 16, |
930 | (unsigned)command & 0xFFFF); | 948 | (unsigned)command & 0xFFFF); |
931 | if (ret == -EPROTO) { | 949 | if (ret == -EPROTO) { |
932 | mutex_unlock(&ir->ir_lock); | 950 | mutex_unlock(&ir->ir_lock); |
@@ -951,7 +969,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, | |||
951 | } | 969 | } |
952 | set_current_state(TASK_UNINTERRUPTIBLE); | 970 | set_current_state(TASK_UNINTERRUPTIBLE); |
953 | schedule_timeout((100 * HZ + 999) / 1000); | 971 | schedule_timeout((100 * HZ + 999) / 1000); |
954 | ir->need_boot = 1; | 972 | tx->need_boot = 1; |
955 | ++failures; | 973 | ++failures; |
956 | } else | 974 | } else |
957 | i += sizeof(int); | 975 | i += sizeof(int); |
@@ -968,22 +986,23 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, | |||
968 | static unsigned int poll(struct file *filep, poll_table *wait) | 986 | static unsigned int poll(struct file *filep, poll_table *wait) |
969 | { | 987 | { |
970 | struct IR *ir = filep->private_data; | 988 | struct IR *ir = filep->private_data; |
989 | struct IR_rx *rx = ir->rx; | ||
971 | unsigned int ret; | 990 | unsigned int ret; |
972 | 991 | ||
973 | dprintk("poll called\n"); | 992 | dprintk("poll called\n"); |
974 | if (ir->c_rx.addr == 0) | 993 | if (rx == NULL) |
975 | return -ENODEV; | 994 | return -ENODEV; |
976 | 995 | ||
977 | mutex_lock(&ir->buf_lock); | 996 | mutex_lock(&rx->buf_lock); |
978 | 997 | ||
979 | poll_wait(filep, &ir->buf.wait_poll, wait); | 998 | poll_wait(filep, &rx->buf.wait_poll, wait); |
980 | 999 | ||
981 | dprintk("poll result = %s\n", | 1000 | dprintk("poll result = %s\n", |
982 | lirc_buffer_empty(&ir->buf) ? "0" : "POLLIN|POLLRDNORM"); | 1001 | lirc_buffer_empty(&rx->buf) ? "0" : "POLLIN|POLLRDNORM"); |
983 | 1002 | ||
984 | ret = lirc_buffer_empty(&ir->buf) ? 0 : (POLLIN|POLLRDNORM); | 1003 | ret = lirc_buffer_empty(&rx->buf) ? 0 : (POLLIN|POLLRDNORM); |
985 | 1004 | ||
986 | mutex_unlock(&ir->buf_lock); | 1005 | mutex_unlock(&rx->buf_lock); |
987 | return ret; | 1006 | return ret; |
988 | } | 1007 | } |
989 | 1008 | ||
@@ -993,9 +1012,9 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
993 | int result; | 1012 | int result; |
994 | unsigned long mode, features = 0; | 1013 | unsigned long mode, features = 0; |
995 | 1014 | ||
996 | if (ir->c_rx.addr != 0) | 1015 | if (ir->rx != NULL) |
997 | features |= LIRC_CAN_REC_LIRCCODE; | 1016 | features |= LIRC_CAN_REC_LIRCCODE; |
998 | if (ir->c_tx.addr != 0) | 1017 | if (ir->tx != NULL) |
999 | features |= LIRC_CAN_SEND_PULSE; | 1018 | features |= LIRC_CAN_SEND_PULSE; |
1000 | 1019 | ||
1001 | switch (cmd) { | 1020 | switch (cmd) { |
@@ -1146,23 +1165,26 @@ static const struct file_operations lirc_fops = { | |||
1146 | static int ir_remove(struct i2c_client *client) | 1165 | static int ir_remove(struct i2c_client *client) |
1147 | { | 1166 | { |
1148 | struct IR *ir = i2c_get_clientdata(client); | 1167 | struct IR *ir = i2c_get_clientdata(client); |
1168 | struct IR_rx *rx = ir->rx; | ||
1169 | struct IR_tx *tx = ir->tx; | ||
1149 | 1170 | ||
1171 | /* FIXME make tx, rx senitive */ | ||
1150 | mutex_lock(&ir->ir_lock); | 1172 | mutex_lock(&ir->ir_lock); |
1151 | 1173 | ||
1152 | if (ir->have_rx || ir->have_tx) { | 1174 | if (rx != NULL || tx != NULL) { |
1153 | DECLARE_COMPLETION(tn); | 1175 | DECLARE_COMPLETION(tn); |
1154 | DECLARE_COMPLETION(tn2); | 1176 | DECLARE_COMPLETION(tn2); |
1155 | 1177 | ||
1156 | /* end up polling thread */ | 1178 | /* end up polling thread */ |
1157 | if (ir->task && !IS_ERR(ir->task)) { | 1179 | if (rx->task && !IS_ERR(rx->task)) { |
1158 | ir->t_notify = &tn; | 1180 | rx->t_notify = &tn; |
1159 | ir->t_notify2 = &tn2; | 1181 | rx->t_notify2 = &tn2; |
1160 | ir->shutdown = 1; | 1182 | rx->shutdown = 1; |
1161 | wake_up_process(ir->task); | 1183 | wake_up_process(rx->task); |
1162 | complete(&tn2); | 1184 | complete(&tn2); |
1163 | wait_for_completion(&tn); | 1185 | wait_for_completion(&tn); |
1164 | ir->t_notify = NULL; | 1186 | rx->t_notify = NULL; |
1165 | ir->t_notify2 = NULL; | 1187 | rx->t_notify2 = NULL; |
1166 | } | 1188 | } |
1167 | 1189 | ||
1168 | } else { | 1190 | } else { |
@@ -1173,13 +1195,15 @@ static int ir_remove(struct i2c_client *client) | |||
1173 | } | 1195 | } |
1174 | 1196 | ||
1175 | /* unregister lirc driver */ | 1197 | /* unregister lirc driver */ |
1198 | /* FIXME make tx, rx senitive */ | ||
1176 | if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) { | 1199 | if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) { |
1177 | lirc_unregister_driver(ir->l.minor); | 1200 | lirc_unregister_driver(ir->l.minor); |
1178 | ir_devices[ir->l.minor] = NULL; | 1201 | ir_devices[ir->l.minor] = NULL; |
1179 | } | 1202 | } |
1180 | 1203 | ||
1181 | /* free memory */ | 1204 | /* free memory */ |
1182 | lirc_buffer_free(&ir->buf); | 1205 | /* FIXME make tx, rx senitive */ |
1206 | lirc_buffer_free(&rx->buf); | ||
1183 | mutex_unlock(&ir->ir_lock); | 1207 | mutex_unlock(&ir->ir_lock); |
1184 | kfree(ir); | 1208 | kfree(ir); |
1185 | 1209 | ||
@@ -1240,18 +1264,37 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1240 | have_rx ? "RX only" : "TX only"); | 1264 | have_rx ? "RX only" : "TX only"); |
1241 | 1265 | ||
1242 | ir = kzalloc(sizeof(struct IR), GFP_KERNEL); | 1266 | ir = kzalloc(sizeof(struct IR), GFP_KERNEL); |
1243 | |||
1244 | if (!ir) | 1267 | if (!ir) |
1245 | goto out_nomem; | 1268 | goto out_nomem; |
1246 | 1269 | ||
1247 | ret = lirc_buffer_init(&ir->buf, 2, BUFLEN / 2); | 1270 | if (have_tx) { |
1248 | if (ret) | 1271 | ir->tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL); |
1249 | goto out_nomem; | 1272 | if (ir->tx != NULL) { |
1273 | ir->tx->need_boot = 1; | ||
1274 | ir->tx->post_tx_ready_poll = | ||
1275 | (id->driver_data & ID_FLAG_HDPVR) ? false : true; | ||
1276 | } | ||
1277 | } | ||
1278 | |||
1279 | if (have_rx) { | ||
1280 | ir->rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL); | ||
1281 | |||
1282 | if (ir->rx == NULL) { | ||
1283 | ret = -ENOMEM; | ||
1284 | } else { | ||
1285 | ir->rx->hdpvr_data_fmt = | ||
1286 | (id->driver_data & ID_FLAG_HDPVR) ? true : false; | ||
1287 | mutex_init(&ir->rx->buf_lock); | ||
1288 | ret = lirc_buffer_init(&ir->rx->buf, 2, BUFLEN / 2); | ||
1289 | } | ||
1290 | |||
1291 | if (ret && (ir->rx != NULL)) { | ||
1292 | kfree(ir->rx); | ||
1293 | ir->rx = NULL; | ||
1294 | } | ||
1295 | } | ||
1250 | 1296 | ||
1251 | mutex_init(&ir->ir_lock); | 1297 | mutex_init(&ir->ir_lock); |
1252 | mutex_init(&ir->buf_lock); | ||
1253 | ir->need_boot = 1; | ||
1254 | ir->is_hdpvr = (id->driver_data & ID_FLAG_HDPVR) ? true : false; | ||
1255 | 1298 | ||
1256 | memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); | 1299 | memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); |
1257 | ir->l.minor = -1; | 1300 | ir->l.minor = -1; |
@@ -1260,40 +1303,38 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1260 | i2c_set_clientdata(client, ir); | 1303 | i2c_set_clientdata(client, ir); |
1261 | 1304 | ||
1262 | /* initialise RX device */ | 1305 | /* initialise RX device */ |
1263 | if (have_rx) { | 1306 | if (ir->rx != NULL) { |
1264 | DECLARE_COMPLETION(tn); | 1307 | DECLARE_COMPLETION(tn); |
1265 | memcpy(&ir->c_rx, client, sizeof(struct i2c_client)); | 1308 | memcpy(&ir->rx->c_rx, client, sizeof(struct i2c_client)); |
1266 | 1309 | ||
1267 | ir->c_rx.addr = 0x71; | 1310 | ir->rx->c_rx.addr = 0x71; |
1268 | strlcpy(ir->c_rx.name, ZILOG_HAUPPAUGE_IR_RX_NAME, | 1311 | strlcpy(ir->rx->c_rx.name, ZILOG_HAUPPAUGE_IR_RX_NAME, |
1269 | I2C_NAME_SIZE); | 1312 | I2C_NAME_SIZE); |
1270 | 1313 | ||
1271 | /* try to fire up polling thread */ | 1314 | /* try to fire up polling thread */ |
1272 | ir->t_notify = &tn; | 1315 | ir->rx->t_notify = &tn; |
1273 | ir->task = kthread_run(lirc_thread, ir, "lirc_zilog"); | 1316 | ir->rx->task = kthread_run(lirc_thread, ir, "lirc_zilog"); |
1274 | if (IS_ERR(ir->task)) { | 1317 | if (IS_ERR(ir->rx->task)) { |
1275 | ret = PTR_ERR(ir->task); | 1318 | ret = PTR_ERR(ir->rx->task); |
1276 | zilog_error("lirc_register_driver: cannot run " | 1319 | zilog_error("lirc_register_driver: cannot run " |
1277 | "poll thread %d\n", ret); | 1320 | "poll thread %d\n", ret); |
1278 | goto err; | 1321 | goto err; |
1279 | } | 1322 | } |
1280 | wait_for_completion(&tn); | 1323 | wait_for_completion(&tn); |
1281 | ir->t_notify = NULL; | 1324 | ir->rx->t_notify = NULL; |
1282 | ir->have_rx = 1; | ||
1283 | } | 1325 | } |
1284 | 1326 | ||
1285 | /* initialise TX device */ | 1327 | /* initialise TX device */ |
1286 | if (have_tx) { | 1328 | if (ir->tx) { |
1287 | memcpy(&ir->c_tx, client, sizeof(struct i2c_client)); | 1329 | memcpy(&ir->tx->c_tx, client, sizeof(struct i2c_client)); |
1288 | ir->c_tx.addr = 0x70; | 1330 | ir->tx->c_tx.addr = 0x70; |
1289 | strlcpy(ir->c_tx.name, ZILOG_HAUPPAUGE_IR_TX_NAME, | 1331 | strlcpy(ir->tx->c_tx.name, ZILOG_HAUPPAUGE_IR_TX_NAME, |
1290 | I2C_NAME_SIZE); | 1332 | I2C_NAME_SIZE); |
1291 | ir->have_tx = 1; | ||
1292 | } | 1333 | } |
1293 | 1334 | ||
1294 | /* set lirc_dev stuff */ | 1335 | /* set lirc_dev stuff */ |
1295 | ir->l.code_length = 13; | 1336 | ir->l.code_length = 13; |
1296 | ir->l.rbuf = &ir->buf; | 1337 | ir->l.rbuf = (ir->rx == NULL) ? NULL : &ir->rx->buf; |
1297 | ir->l.fops = &lirc_fops; | 1338 | ir->l.fops = &lirc_fops; |
1298 | ir->l.data = ir; | 1339 | ir->l.data = ir; |
1299 | ir->l.minor = minor; | 1340 | ir->l.minor = minor; |
@@ -1317,9 +1358,9 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1317 | * after registering with lirc as otherwise hotplug seems to take | 1358 | * after registering with lirc as otherwise hotplug seems to take |
1318 | * 10s to create the lirc device. | 1359 | * 10s to create the lirc device. |
1319 | */ | 1360 | */ |
1320 | if (have_tx) { | 1361 | if (ir->tx != NULL) { |
1321 | /* Special TX init */ | 1362 | /* Special TX init */ |
1322 | ret = tx_init(ir); | 1363 | ret = tx_init(ir->tx); |
1323 | if (ret != 0) | 1364 | if (ret != 0) |
1324 | goto err; | 1365 | goto err; |
1325 | } | 1366 | } |
@@ -1327,18 +1368,21 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1327 | return 0; | 1368 | return 0; |
1328 | 1369 | ||
1329 | err: | 1370 | err: |
1371 | /* FIXME - memory deallocation for all error cases needs work */ | ||
1330 | /* undo everything, hopefully... */ | 1372 | /* undo everything, hopefully... */ |
1331 | if (ir->c_rx.addr) | 1373 | if (ir->rx != NULL) |
1332 | ir_remove(&ir->c_rx); | 1374 | ir_remove(&ir->rx->c_rx); |
1333 | if (ir->c_tx.addr) | 1375 | if (ir->tx != NULL) |
1334 | ir_remove(&ir->c_tx); | 1376 | ir_remove(&ir->tx->c_tx); |
1335 | return ret; | 1377 | return ret; |
1336 | 1378 | ||
1337 | out_nodev: | 1379 | out_nodev: |
1380 | /* FIXME - memory deallocation for all error cases needs work */ | ||
1338 | zilog_error("no device found\n"); | 1381 | zilog_error("no device found\n"); |
1339 | return -ENODEV; | 1382 | return -ENODEV; |
1340 | 1383 | ||
1341 | out_nomem: | 1384 | out_nomem: |
1385 | /* FIXME - memory deallocation for all error cases needs work */ | ||
1342 | zilog_error("memory allocation failure\n"); | 1386 | zilog_error("memory allocation failure\n"); |
1343 | kfree(ir); | 1387 | kfree(ir); |
1344 | return -ENOMEM; | 1388 | return -ENOMEM; |