gfx_tv.c revision f29dbc25
1/* Copyright (c) 2005 Advanced Micro Devices, Inc. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 * 21 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22 * contributors may be used to endorse or promote products derived from this 23 * software without specific prior written permission. 24 * */ 25 26/* 27 * This file contains routines to program TVOUT and TV encoder. 28 * 29 * Routines: 30 * 31 * gfx_set_tv_format 32 * gfx_set_tv_output 33 * gfx_set_tv_enable 34 * gfx_set_tv_flicker_filter 35 * gfx_set_tv_sub_carrier_reset 36 * gfx_set_tv_vphase 37 * gfx_set_tv_YC_delay 38 * gfx_set_tvenc_reset_interval 39 * gfx_set_tv_cc_enable 40 * gfx_set_tv_cc_data 41 * gfx_test_tvout_odd_field 42 * gfx_test_tvenc_odd_field 43 * gfx_set_tv_field_status_invert 44 * gfx_get_tv_vphase 45 * */ 46 47/* TV TIMINGS */ 48 49DISPLAYMODE TVTimings[] = { 50 51/* NTSC resolution */ 52 53 {0x3 | /* negative syncs */ 54 GFX_MODE_TV_NTSC, /* NTSC format */ 55 640, 640, 656, 744, 792, 792, /* horizontal timings */ 56 480, 480, 490, 492, 517, 525, /* vertical timings */ 57 0x0018EC4D, /* freq = 24.923052 MHz */ 58 } 59 , 60 61/* PAL resolution */ 62 63 {0x3 | /* negative syncs */ 64 GFX_MODE_TV_PAL, /* PAL format */ 65 768, 768, 800, 848, 864, 864, /* horizontal timings */ 66 576, 576, 586, 588, 625, 625, /* vertical timings */ 67 0x001B0000, /* freq = 27.00 MHz */ 68 } 69 , 70 71/* NTSC resolution non-square pixels */ 72 73 {0x3 | /* negative syncs */ 74 GFX_MODE_TV_NTSC, /* NTSC format */ 75 720, 720, 736, 752, 792, 792, /* horizontal timings */ 76 480, 480, 490, 492, 517, 525, /* vertical timings */ 77 0x0018EC4D, /* freq = 24.923052 MHz */ 78 } 79 , 80 81/* PAL resolution non-square pixels */ 82 83 {0x3 | /* negative syncs */ 84 GFX_MODE_TV_PAL, /* PAL format */ 85 720, 720, 752, 816, 864, 864, /* horizontal timings */ 86 576, 576, 586, 588, 625, 625, /* vertical timings */ 87 0x001B0000, /* freq = 27.00 MHz */ 88 } 89}; 90 91#define NUM_TV_MODES sizeof(TVTimings)/sizeof(DISPLAYMODE) 92 93/* INCLUDE SUPPORT FOR SC1200 TV ENCODER, IF SPECIFIED */ 94 95#if GFX_TV_SC1200 96#include "tv_1200.c" 97#endif 98 99/* INCLUDE SUPPORT FOR FS450 TV ENCODER, IF SPECIFIED */ 100 101#if GFX_TV_FS451 102#include "tv_fs450.c" 103#endif 104 105/* WRAPPERS IF DYNAMIC SELECTION */ 106/* Extra layer to call either SC1200 or FS450 TV encoder routines. */ 107 108#if GFX_TV_DYNAMIC 109 110/*---------------------------------------------------------------------------- 111 * gfx_set_tv_format 112 *---------------------------------------------------------------------------- 113 */ 114int 115gfx_set_tv_format(TVStandardType format, GfxOnTVType resolution) 116{ 117 int retval = GFX_STATUS_UNSUPPORTED; 118 119#if GFX_TV_SC1200 120 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 121 retval = sc1200_set_tv_format(format, resolution); 122#endif 123#if GFX_TV_FS451 124 if (gfx_tv_type & GFX_TV_TYPE_FS451) 125 retval = fs450_set_tv_format(format, resolution); 126#endif 127 return (retval); 128} 129 130/*---------------------------------------------------------------------------- 131 * gfx_set_tv_output 132 *---------------------------------------------------------------------------- 133 */ 134int 135gfx_set_tv_output(int output) 136{ 137 int retval = GFX_STATUS_UNSUPPORTED; 138 139#if GFX_TV_SC1200 140 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 141 retval = sc1200_set_tv_output(output); 142#endif 143#if GFX_TV_FS451 144 if (gfx_tv_type & GFX_TV_TYPE_FS451) 145 retval = fs450_set_tv_output(output); 146#endif 147 return (retval); 148} 149 150/*---------------------------------------------------------------------------- 151 * gfx_set_tv_enable 152 *---------------------------------------------------------------------------- 153 */ 154int 155gfx_set_tv_enable(int enable) 156{ 157 int retval = GFX_STATUS_UNSUPPORTED; 158 159#if GFX_TV_SC1200 160 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 161 retval = sc1200_set_tv_enable(enable); 162#endif 163#if GFX_TV_FS451 164 if (gfx_tv_type & GFX_TV_TYPE_FS451) 165 retval = fs450_set_tv_enable(enable); 166#endif 167 return (retval); 168} 169 170/*---------------------------------------------------------------------------- 171 * gfx_set_tv_flicker_filter 172 *---------------------------------------------------------------------------- 173 */ 174int 175gfx_set_tv_flicker_filter(int ff) 176{ 177 int retval = GFX_STATUS_UNSUPPORTED; 178 179#if GFX_TV_SC1200 180 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 181 retval = sc1200_set_tv_flicker_filter(ff); 182#endif 183 return (retval); 184} 185 186/*---------------------------------------------------------------------------- 187 * gfx_set_tv_sub_carrier_reset 188 *---------------------------------------------------------------------------- 189 */ 190int 191gfx_set_tv_sub_carrier_reset(int screset) 192{ 193 int retval = GFX_STATUS_UNSUPPORTED; 194 195#if GFX_TV_SC1200 196 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 197 retval = sc1200_set_tv_sub_carrier_reset(screset); 198#endif 199 return (retval); 200} 201 202/*---------------------------------------------------------------------------- 203 * gfx_set_tv_vphase 204 *---------------------------------------------------------------------------- 205 */ 206int 207gfx_set_tv_vphase(int vphase) 208{ 209 int retval = GFX_STATUS_UNSUPPORTED; 210 211#if GFX_TV_SC1200 212 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 213 retval = sc1200_set_tv_vphase(vphase); 214#endif 215 return (retval); 216} 217 218/*---------------------------------------------------------------------------- 219 * gfx_set_tv_YC_delay 220 *---------------------------------------------------------------------------- 221 */ 222int 223gfx_set_tv_YC_delay(int delay) 224{ 225 int retval = GFX_STATUS_UNSUPPORTED; 226 227#if GFX_TV_SC1200 228 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 229 retval = sc1200_set_tv_YC_delay(delay); 230#endif 231 return (retval); 232} 233 234/*---------------------------------------------------------------------------- 235 * gfx_set_tvenc_reset_interval 236 *---------------------------------------------------------------------------- 237 */ 238int 239gfx_set_tvenc_reset_interval(int interval) 240{ 241 int retval = GFX_STATUS_UNSUPPORTED; 242 243#if GFX_TV_SC1200 244 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 245 retval = sc1200_set_tvenc_reset_interval(interval); 246#endif 247 return (retval); 248} 249 250/*---------------------------------------------------------------------------- 251 * gfx_set_tv_cc_enable 252 *---------------------------------------------------------------------------- 253 */ 254int 255gfx_set_tv_cc_enable(int enable) 256{ 257 int retval = GFX_STATUS_UNSUPPORTED; 258 259#if GFX_TV_SC1200 260 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 261 retval = sc1200_set_tv_cc_enable(enable); 262#endif 263 return (retval); 264} 265 266/*---------------------------------------------------------------------------- 267 * gfx_set_tv_cc_data 268 * 269 * This routine writes the two specified characters to the CC data register 270 * of the TV encoder. 271 *---------------------------------------------------------------------------- 272 */ 273int 274gfx_set_tv_cc_data(unsigned char data1, unsigned char data2) 275{ 276 int retval = GFX_STATUS_UNSUPPORTED; 277 278#if GFX_TV_SC1200 279 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 280 retval = sc1200_set_tv_cc_data(data1, data2); 281#endif 282 return (retval); 283} 284 285/*--------------------------------------------------------------------------- 286 * gfx_set_tv_display 287 * 288 * Set the timings in the display controller to support a TV resolution. 289 *--------------------------------------------------------------------------- 290 */ 291int 292gfx_set_tv_display(int width, int height) 293{ 294 int status = GFX_STATUS_UNSUPPORTED; 295 296#if GFX_TV_SC1200 297 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 298 status = sc1200_set_tv_display(width, height); 299#endif 300 return (status); 301} 302 303/*--------------------------------------------------------------------------- 304 * gfx_test_tvout_odd_field 305 *--------------------------------------------------------------------------- 306 */ 307int 308gfx_test_tvout_odd_field(void) 309{ 310 int status = GFX_STATUS_UNSUPPORTED; 311 312#if GFX_TV_SC1200 313 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 314 status = sc1200_test_tvout_odd_field(); 315#endif 316 return (status); 317} 318 319/*--------------------------------------------------------------------------- 320 * gfx_test_tvenc_odd_field 321 *--------------------------------------------------------------------------- 322 */ 323int 324gfx_test_tvenc_odd_field(void) 325{ 326 int status = GFX_STATUS_UNSUPPORTED; 327 328#if GFX_TV_SC1200 329 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 330 status = sc1200_test_tvenc_odd_field(); 331#endif 332 return (status); 333} 334 335/*---------------------------------------------------------------------------- 336 * gfx_set_tv_field_status_invert 337 *---------------------------------------------------------------------------- 338 */ 339int 340gfx_set_tv_field_status_invert(int enable) 341{ 342 int retval = GFX_STATUS_UNSUPPORTED; 343 344#if GFX_TV_SC1200 345 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 346 retval = sc1200_set_tv_field_status_invert(enable); 347#endif 348 return (retval); 349} 350 351/*--------------------------------------------------------------------------- 352 * gfx_get_tv_vphase 353 *--------------------------------------------------------------------------- 354 */ 355int 356gfx_get_tv_vphase(void) 357{ 358 int status = GFX_STATUS_UNSUPPORTED; 359 360#if GFX_TV_SC1200 361 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 362 status = sc1200_get_tv_vphase(); 363#endif 364 return (status); 365} 366 367/*--------------------------------------------------------------------------- 368 * gfx_get_tv_enable 369 *--------------------------------------------------------------------------- 370 */ 371int 372gfx_get_tv_enable(unsigned int *p_on) 373{ 374 int retval = -1; 375 376#if GFX_TV_FS451 377 if (gfx_tv_type & GFX_TV_TYPE_FS451) 378 retval = fs450_get_tv_enable(p_on); 379#endif 380#if GFX_TV_SC1200 381 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 382 retval = sc1200_get_tv_enable(p_on); 383#endif 384 return (retval); 385} 386 387/*--------------------------------------------------------------------------- 388 * gfx_get_tv_output 389 *--------------------------------------------------------------------------- 390 */ 391int 392gfx_get_tv_output() 393{ 394 int retval = -1; 395 396#if GFX_TV_SC1200 397 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 398 retval = sc1200_get_tv_output(); 399#endif 400 return (retval); 401} 402 403/*--------------------------------------------------------------------------- 404 * gfx_get_tv_mode_count 405 *--------------------------------------------------------------------------- 406 */ 407int 408gfx_get_tv_mode_count(TVStandardType format) 409{ 410 int retval = -1; 411 412#if GFX_TV_SC1200 413 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 414 retval = sc1200_get_tv_mode_count(format); 415#endif 416 return (retval); 417} 418 419/*--------------------------------------------------------------------------- 420 * gfx_get_tv_display_mode 421 *--------------------------------------------------------------------------- 422 */ 423int 424gfx_get_tv_display_mode(int *width, int *height, int *bpp, int *hz) 425{ 426 int retval = -1; 427 428#if GFX_TV_SC1200 429 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 430 retval = sc1200_get_tv_display_mode(width, height, bpp, hz); 431#endif 432 return (retval); 433} 434 435/*--------------------------------------------------------------------------- 436 * gfx_get_tv_display_mode_frequency 437 *--------------------------------------------------------------------------- 438 */ 439int 440gfx_get_tv_display_mode_frequency(unsigned short width, unsigned short height, 441 TVStandardType format, int *frequency) 442{ 443 int retval = -1; 444 445#if GFX_TV_SC1200 446 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 447 retval = 448 sc1200_get_tv_display_mode_frequency(width, height, format, 449 frequency); 450#endif 451 return (retval); 452} 453 454/*--------------------------------------------------------------------------- 455 * gfx_is_tv_display_mode_supported 456 *--------------------------------------------------------------------------- 457 */ 458int 459gfx_is_tv_display_mode_supported(unsigned short width, unsigned short height, 460 TVStandardType format) 461{ 462 int retval = -1; 463 464#if GFX_TV_SC1200 465 if (gfx_tv_type & GFX_TV_TYPE_SC1200) 466 retval = sc1200_is_tv_display_mode_supported(width, height, format); 467#endif 468 return (retval); 469} 470 471/*------------------------------------------ 472 * The following functions were added to support 473 * the FS450 and will eventually be removed. There 474 * is no equivalent support in the SC1200. 475 *----------------------------------------------*/ 476 477/*========================================================================== 478 * TV standard 479 *========================================================================== 480 */ 481int 482gfx_get_tv_standard(unsigned long *p_standard) 483{ 484 int retval = -1; 485 486#if GFX_TV_FS451 487 if (gfx_tv_type & GFX_TV_TYPE_FS451) 488 retval = fs450_get_tv_standard(p_standard); 489#endif 490 return (retval); 491} 492 493int 494gfx_get_available_tv_standards(unsigned long *p_standards) 495{ 496 int retval = -1; 497 498#if GFX_TV_FS451 499 if (gfx_tv_type & GFX_TV_TYPE_FS451) 500 retval = fs450_get_available_tv_standards(p_standards); 501#endif 502 return (retval); 503} 504 505int 506gfx_set_tv_standard(unsigned long standard) 507{ 508 int retval = -1; 509 510#if GFX_TV_FS451 511 if (gfx_tv_type & GFX_TV_TYPE_FS451) 512 retval = fs450_set_tv_standard(standard); 513#endif 514 return (retval); 515} 516 517/* 518 *========================================================================== 519 * vga mode as known by the driver 520 *========================================================================== 521 */ 522int 523gfx_get_tv_vga_mode(unsigned long *p_vga_mode) 524{ 525 int retval = -1; 526 527#if GFX_TV_FS451 528 if (gfx_tv_type & GFX_TV_TYPE_FS451) 529 retval = fs450_get_tv_vga_mode(p_vga_mode); 530#endif 531 return (retval); 532} 533 534int 535gfx_get_available_tv_vga_modes(unsigned long *p_vga_modes) 536{ 537 int retval = -1; 538 539#if GFX_TV_FS451 540 if (gfx_tv_type & GFX_TV_TYPE_FS451) 541 retval = fs450_get_available_tv_vga_modes(p_vga_modes); 542#endif 543 return (retval); 544} 545 546int 547gfx_set_tv_vga_mode(unsigned long vga_mode) 548{ 549 int re tval = -1; 550 551#if GFX_TV_FS451 552 if (gfx_tv_type & GFX_TV_TYPE_FS451) 553 retval = fs450_set_tv_vga_mode(vga_mode); 554#endif 555 return (retval); 556} 557 558/* 559 *========================================================================== 560 * 561 * tvout mode 562 */ 563 564int 565gfx_get_tvout_mode(unsigned long *p_tvout_mode) 566{ 567 int retval = -1; 568 569#if GFX_TV_FS451 570 if (gfx_tv_type & GFX_TV_TYPE_FS451) 571 retval = fs450_get_tvout_mode(p_tvout_mode); 572#endif 573 return (retval); 574} 575 576int 577gfx_set_tvout_mode(unsigned long tvout_mode) 578{ 579 int retval = -1; 580 581#if GFX_TV_FS451 582 if (gfx_tv_type & GFX_TV_TYPE_FS451) 583 retval = fs450_set_tvout_mode(tvout_mode); 584#endif 585 return (retval); 586} 587 588/* 589 *========================================================================== 590 * 591 * Sharpness 592 */ 593int 594gfx_get_sharpness(int *p_sharpness) 595{ 596 int retval = -1; 597 598#if GFX_TV_FS451 599 if (gfx_tv_type & GFX_TV_TYPE_FS451) 600 retval = fs450_get_sharpness(p_sharpness); 601#endif 602 return (retval); 603} 604 605int 606gfx_set_sharpness(int sharpness) 607{ 608 int retval = -1; 609 610#if GFX_TV_FS451 611 if (gfx_tv_type & GFX_TV_TYPE_FS451) 612 retval = fs450_set_sharpness(sharpness); 613#endif 614 return (retval); 615} 616 617/* 618 *========================================================================== 619 * 620 * flicker filter control. 621 */ 622 623int 624gfx_get_flicker_filter(int *p_flicker) 625{ 626 int retval = -1; 627 628#if GFX_TV_FS451 629 if (gfx_tv_type & GFX_TV_TYPE_FS451) 630 retval = fs450_get_flicker_filter(p_flicker); 631#endif 632 return (retval); 633} 634 635int 636gfx_set_flicker_filter(int flicker) 637{ 638 int retval = -1; 639 640#if GFX_TV_FS451 641 if (gfx_tv_type & GFX_TV_TYPE_FS451) 642 retval = fs450_set_flicker_filter(flicker); 643#endif 644 return (retval); 645} 646 647/* 648 *========================================================================== 649 * 650 * Overscan and Position 651 */ 652 653int 654gfx_get_overscan(int *p_x, int *p_y) 655{ 656 int retval = -1; 657 658#if GFX_TV_FS451 659 if (gfx_tv_type & GFX_TV_TYPE_FS451) 660 retval = fs450_get_overscan(p_x, p_y); 661#endif 662 return (retval); 663 664} 665 666int 667gfx_set_overscan(int x, int y) 668{ 669 int retval = -1; 670 671#if GFX_TV_FS451 672 if (gfx_tv_type & GFX_TV_TYPE_FS451) 673 retval = fs450_set_overscan(x, y); 674#endif 675 return (retval); 676} 677 678int 679gfx_get_position(int *p_x, int *p_y) 680{ 681 int retval = -1; 682 683#if GFX_TV_FS451 684 if (gfx_tv_type & GFX_TV_TYPE_FS451) 685 retval = fs450_get_position(p_x, p_y); 686#endif 687 return (retval); 688} 689 690int 691gfx_set_position(int x, int y) 692{ 693 int retval = -1; 694 695#if GFX_TV_FS451 696 if (gfx_tv_type & GFX_TV_TYPE_FS451) 697 retval = fs450_set_position(x, y); 698#endif 699 return (retval); 700} 701 702/* 703 *========================================================================== 704 * 705 * Color, Brightness, and Contrast 706 */ 707 708int 709gfx_get_color(int *p_color) 710{ 711 int retval = -1; 712 713#if GFX_TV_FS451 714 if (gfx_tv_type & GFX_TV_TYPE_FS451) 715 retval = fs450_get_color(p_color); 716#endif 717 return (retval); 718} 719 720int 721gfx_set_color(int color) 722{ 723 int retval = -1; 724 725#if GFX_TV_FS451 726 if (gfx_tv_type & GFX_TV_TYPE_FS451) 727 retval = fs450_set_color(color); 728#endif 729 return (retval); 730} 731 732int 733gfx_get_brightness(int *p_brightness) 734{ 735 int retval = -1; 736 737#if GFX_TV_FS451 738 if (gfx_tv_type & GFX_TV_TYPE_FS451) 739 retval = fs450_get_brightness(p_brightness); 740#endif 741 return (retval); 742} 743 744int 745gfx_set_brightness(int brightness) 746{ 747 int retval = -1; 748 749#if GFX_TV_FS451 750 if (gfx_tv_type & GFX_TV_TYPE_FS451) 751 retval = fs450_set_brightness(brightness); 752#endif 753 return (retval); 754} 755 756int 757gfx_get_contrast(int *p_contrast) 758{ 759 int retval = -1; 760 761#if GFX_TV_FS451 762 if (gfx_tv_type & GFX_TV_TYPE_FS451) 763 retval = fs450_get_contrast(p_contrast); 764#endif 765 return (retval); 766} 767 768int 769gfx_set_contrast(int contrast) 770{ 771 int retval = -1; 772 773#if GFX_TV_FS451 774 if (gfx_tv_type & GFX_TV_TYPE_FS451) 775 retval = fs450_set_contrast(contrast); 776#endif 777 return (retval); 778} 779 780/* 781 *========================================================================== 782 * 783 * YC filters 784 */ 785 786int 787gfx_get_yc_filter(unsigned int *p_yc_filter) 788{ 789 int retval = -1; 790 791#if GFX_TV_FS451 792 if (gfx_tv_type & GFX_TV_TYPE_FS451) 793 retval = fs450_get_yc_filter(p_yc_filter); 794#endif 795 return (retval); 796} 797 798int 799gfx_set_yc_filter(unsigned int yc_filter) 800{ 801 int retval = -1; 802 803#if GFX_TV_FS451 804 if (gfx_tv_type & GFX_TV_TYPE_FS451) 805 retval = fs450_set_yc_filter(yc_filter); 806#endif 807 return (retval); 808} 809 810int 811gfx_get_aps_trigger_bits(unsigned int *p_trigger_bits) 812{ 813 int retval = -1; 814 815#if GFX_TV_FS451 816 if (gfx_tv_type & GFX_TV_TYPE_FS451) 817 retval = fs450_get_aps_trigger_bits(p_trigger_bits); 818#endif 819 return (retval); 820} 821 822int 823gfx_set_aps_trigger_bits(unsigned int trigger_bits) 824{ 825 int retval = -1; 826 827#if GFX_TV_FS451 828 if (gfx_tv_type & GFX_TV_TYPE_FS451) 829 retval = fs450_set_aps_trigger_bits(trigger_bits); 830#endif 831 return (retval); 832} 833 834#endif /* GFX_TV_DYNAMIC */ 835 836/* END OF FILE */ 837