Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (3384): Separate tv & radio freqs, fix cb/freq transmit order for tuners that need this.

- Moved MSP_SET_MATRIX to v4l2-common.h
- Fix typos and integer overflows in tea5767.c
- Split old freq field into a tv_freq and a radio_freq. Prevents
that a radio tuner is initialized with a tv frequency or vice versa.
- When switching to radio mode initialize the tuner with the last
used radio frequency (this was already done for the TV mode).
As a result of these changes the tuner module now remembers the
last set radio and TV frequencies, which is what you would expect
to happen.
- Move out of range frequencies to the closest valid frequency as per
v4l2 API spec.
- Fix incorrect initial radio frequency (multiplier is 16000, not 16)
- Add boundary check for out of range frequencies.
- Use new flag to check if the order of the CB and freq. depends on
the last set frequency. That is needed for some tuners or you can
get static as a result. The flag is added for those tuners where I know
that the datasheet indicates that this is necessary.
- For this new check use the last set div value, not the last frequency
as radio frequencies are always much higher due to the 16000 multiplier.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
27487d44 8f0bb9c0

+129 -82
-8
drivers/media/video/msp3400.h
··· 6 6 7 7 /* ---------------------------------------------------------------------- */ 8 8 9 - struct msp_matrix { 10 - int input; 11 - int output; 12 - }; 13 - 14 - /* ioctl for MSP_SET_MATRIX will have to be registered */ 15 - #define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix) 16 - 17 9 /* This macro is allowed for *constants* only, gcc must calculate it 18 10 at compile time. Remember -- no floats in kernel mode */ 19 11 #define MSP_CARRIER(freq) ((int)((float)(freq / 18.432) * (1 << 24)))
+6 -6
drivers/media/video/mt20xx.c
··· 353 353 } while (xok != 1 ); 354 354 t->xogc=xogc; 355 355 356 - t->tv_freq = mt2032_set_tv_freq; 357 - t->radio_freq = mt2032_set_radio_freq; 356 + t->set_tv_freq = mt2032_set_tv_freq; 357 + t->set_radio_freq = mt2032_set_radio_freq; 358 358 return(1); 359 359 } 360 360 ··· 481 481 i2c_master_recv(c,buf,1); 482 482 483 483 tuner_dbg("mt2050: sro is %x\n",buf[0]); 484 - t->tv_freq = mt2050_set_tv_freq; 485 - t->radio_freq = mt2050_set_radio_freq; 484 + t->set_tv_freq = mt2050_set_tv_freq; 485 + t->set_radio_freq = mt2050_set_radio_freq; 486 486 return 0; 487 487 } 488 488 ··· 494 494 int company_code; 495 495 496 496 memset(buf,0,sizeof(buf)); 497 - t->tv_freq = NULL; 498 - t->radio_freq = NULL; 497 + t->set_tv_freq = NULL; 498 + t->set_radio_freq = NULL; 499 499 t->standby = NULL; 500 500 if (t->std & V4L2_STD_525_60) { 501 501 tuner_dbg("pinnacle ntsc\n");
+2 -2
drivers/media/video/tda8290.c
··· 567 567 } 568 568 tuner_info("tuner: type set to %s\n", c->name); 569 569 570 - t->tv_freq = set_tv_freq; 571 - t->radio_freq = set_radio_freq; 570 + t->set_tv_freq = set_tv_freq; 571 + t->set_radio_freq = set_radio_freq; 572 572 t->has_signal = has_signal; 573 573 t->standby = standby; 574 574 t->tda827x_lpsel = 0;
+9 -9
drivers/media/video/tea5767.c
··· 62 62 63 63 #define TEA5767_PORT1_HIGH 0x01 64 64 65 - /* Forth register */ 65 + /* Fourth register */ 66 66 #define TEA5767_PORT2_HIGH 0x80 67 67 /* Chips stops working. Only I2C bus remains on */ 68 68 #define TEA5767_STDBY 0x40 ··· 85 85 /* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */ 86 86 #define TEA5767_SRCH_IND 0x01 87 87 88 - /* Fiveth register */ 88 + /* Fifth register */ 89 89 90 90 /* By activating, it will use Xtal at 13 MHz as reference for divider */ 91 91 #define TEA5767_PLLREF_ENABLE 0x80 ··· 109 109 #define TEA5767_STEREO_MASK 0x80 110 110 #define TEA5767_IF_CNTR_MASK 0x7f 111 111 112 - /* Four register */ 112 + /* Fourth register */ 113 113 #define TEA5767_ADC_LEVEL_MASK 0xf0 114 114 115 115 /* should be 0 */ 116 116 #define TEA5767_CHIP_ID_MASK 0x0f 117 117 118 - /* Fiveth register */ 118 + /* Fifth register */ 119 119 /* Reserved for future extensions */ 120 120 #define TEA5767_RESERVED_MASK 0xff 121 121 ··· 220 220 tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); 221 221 buffer[2] |= TEA5767_HIGH_LO_INJECT; 222 222 buffer[4] |= TEA5767_PLLREF_ENABLE; 223 - div = (frq * 4000 / 16 + 700000 + 225000 + 25000) / 50000; 223 + div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000; 224 224 break; 225 225 case TEA5767_LOW_LO_13MHz: 226 226 tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); 227 227 228 228 buffer[4] |= TEA5767_PLLREF_ENABLE; 229 - div = (frq * 4000 / 16 - 700000 - 225000 + 25000) / 50000; 229 + div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000; 230 230 break; 231 231 case TEA5767_LOW_LO_32768: 232 232 tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); 233 233 buffer[3] |= TEA5767_XTAL_32768; 234 234 /* const 700=4000*175 Khz - to adjust freq to right value */ 235 - div = ((frq * 4000 / 16 - 700000 - 225000) + 16384) >> 15; 235 + div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15; 236 236 break; 237 237 case TEA5767_HIGH_LO_32768: 238 238 default: ··· 350 350 tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio"); 351 351 strlcpy(c->name, "tea5767", sizeof(c->name)); 352 352 353 - t->tv_freq = set_tv_freq; 354 - t->radio_freq = set_radio_freq; 353 + t->set_tv_freq = set_tv_freq; 354 + t->set_radio_freq = set_radio_freq; 355 355 t->has_signal = tea5767_signal; 356 356 t->is_stereo = tea5767_stereo; 357 357 t->standby = tea5767_standby;
+52 -33
drivers/media/video/tuner-core.c
··· 82 82 tuner_warn ("tuner type not set\n"); 83 83 return; 84 84 } 85 - if (NULL == t->tv_freq) { 85 + if (NULL == t->set_tv_freq) { 86 86 tuner_warn ("Tuner has no way to set tv freq\n"); 87 87 return; 88 88 } ··· 90 90 tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n", 91 91 freq / 16, freq % 16 * 100 / 16, tv_range[0], 92 92 tv_range[1]); 93 + /* V4L2 spec: if the freq is not possible then the closest 94 + possible value should be selected */ 95 + if (freq < tv_range[0] * 16) 96 + freq = tv_range[0] * 16; 97 + else 98 + freq = tv_range[1] * 16; 93 99 } 94 - t->tv_freq(c, freq); 100 + t->set_tv_freq(c, freq); 95 101 } 96 102 97 103 static void set_radio_freq(struct i2c_client *c, unsigned int freq) ··· 108 102 tuner_warn ("tuner type not set\n"); 109 103 return; 110 104 } 111 - if (NULL == t->radio_freq) { 105 + if (NULL == t->set_radio_freq) { 112 106 tuner_warn ("tuner has no way to set radio frequency\n"); 113 107 return; 114 108 } 115 - if (freq <= radio_range[0] * 16000 || freq >= radio_range[1] * 16000) { 109 + if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) { 116 110 tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n", 117 111 freq / 16000, freq % 16000 * 100 / 16000, 118 112 radio_range[0], radio_range[1]); 113 + /* V4L2 spec: if the freq is not possible then the closest 114 + possible value should be selected */ 115 + if (freq < radio_range[0] * 16000) 116 + freq = radio_range[0] * 16000; 117 + else 118 + freq = radio_range[1] * 16000; 119 119 } 120 120 121 - t->radio_freq(c, freq); 122 - return; 121 + t->set_radio_freq(c, freq); 123 122 } 124 123 125 124 static void set_freq(struct i2c_client *c, unsigned long freq) ··· 136 125 tuner_dbg("radio freq set to %lu.%02lu\n", 137 126 freq / 16000, freq % 16000 * 100 / 16000); 138 127 set_radio_freq(c, freq); 128 + t->radio_freq = freq; 139 129 break; 140 130 case V4L2_TUNER_ANALOG_TV: 141 131 case V4L2_TUNER_DIGITAL_TV: 142 132 tuner_dbg("tv freq set to %lu.%02lu\n", 143 133 freq / 16, freq % 16 * 100 / 16); 144 134 set_tv_freq(c, freq); 135 + t->tv_freq = freq; 145 136 break; 146 137 } 147 - t->freq = freq; 148 138 } 149 139 150 140 static void set_type(struct i2c_client *c, unsigned int type, ··· 224 212 if (t->mode_mask == T_UNINITIALIZED) 225 213 t->mode_mask = new_mode_mask; 226 214 227 - set_freq(c, t->freq); 215 + set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? t->radio_freq : t->tv_freq); 228 216 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", 229 217 c->adapter->name, c->driver->driver.name, c->addr << 1, type, 230 218 t->mode_mask); ··· 389 377 default: p = "undefined"; break; 390 378 } 391 379 if (t->mode == V4L2_TUNER_RADIO) { 392 - freq = t->freq / 16000; 393 - freq_fraction = (t->freq % 16000) * 100 / 16000; 380 + freq = t->radio_freq / 16000; 381 + freq_fraction = (t->radio_freq % 16000) * 100 / 16000; 394 382 } else { 395 - freq = t->freq / 16; 396 - freq_fraction = (t->freq % 16) * 100 / 16; 383 + freq = t->tv_freq / 16; 384 + freq_fraction = (t->tv_freq % 16) * 100 / 16; 397 385 } 398 386 tuner_info("Tuner mode: %s\n", p); 399 387 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); ··· 468 456 t->type = TUNER_TEA5767; 469 457 t->mode_mask = T_RADIO; 470 458 t->mode = T_STANDBY; 471 - t->freq = 87.5 * 16; /* Sets freq to FM range */ 459 + t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ 472 460 default_mode_mask &= ~T_RADIO; 473 461 474 462 goto register_client; ··· 481 469 if (default_mode_mask != T_UNINITIALIZED) { 482 470 tuner_dbg ("Setting mode_mask to 0x%02x\n", default_mode_mask); 483 471 t->mode_mask = default_mode_mask; 484 - t->freq = 400 * 16; /* Sets freq to VHF High */ 472 + t->tv_freq = 400 * 16; /* Sets freq to VHF High */ 473 + t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ 485 474 default_mode_mask = T_UNINITIALIZED; 486 475 } 487 476 ··· 578 565 set_addr(client, (struct tuner_setup *)arg); 579 566 break; 580 567 case AUDC_SET_RADIO: 581 - set_mode(client,t,V4L2_TUNER_RADIO, "AUDC_SET_RADIO"); 568 + if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO") 569 + == EINVAL) 570 + return 0; 571 + if (t->radio_freq) 572 + set_freq(client, t->radio_freq); 582 573 break; 583 574 case TUNER_SET_STANDBY: 584 - { 585 - if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) 586 - return 0; 587 - if (t->standby) 588 - t->standby (client); 589 - break; 590 - } 575 + if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) 576 + return 0; 577 + if (t->standby) 578 + t->standby (client); 579 + break; 591 580 case VIDIOCSAUDIO: 592 581 if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) 593 582 return 0; ··· 598 583 599 584 /* Should be implemented, since bttv calls it */ 600 585 tuner_dbg("VIDIOCSAUDIO not implemented.\n"); 601 - 602 586 break; 603 587 /* --- v4l ioctls --- */ 604 588 /* take care: bttv does userspace copying, we'll get a ··· 623 609 if (vc->norm < ARRAY_SIZE(map)) 624 610 t->std = map[vc->norm]; 625 611 tuner_fixup_std(t); 626 - if (t->freq) 627 - set_tv_freq(client, t->freq); 612 + if (t->tv_freq) 613 + set_tv_freq(client, t->tv_freq); 628 614 return 0; 629 615 } 630 616 case VIDIOCSFREQ: ··· 698 684 699 685 t->std = *id; 700 686 tuner_fixup_std(t); 701 - if (t->freq) 702 - set_freq(client, t->freq); 687 + if (t->tv_freq) 688 + set_freq(client, t->tv_freq); 703 689 break; 704 690 } 705 691 case VIDIOC_S_FREQUENCY: 706 692 { 707 693 struct v4l2_frequency *f = arg; 708 694 709 - t->freq = f->frequency; 710 695 switch_v4l2(); 711 696 if (V4L2_TUNER_RADIO == f->type && 712 697 V4L2_TUNER_RADIO != t->mode) { ··· 713 700 == EINVAL) 714 701 return 0; 715 702 } 716 - set_freq(client,t->freq); 703 + set_freq(client,f->frequency); 717 704 718 705 break; 719 706 } ··· 725 712 return 0; 726 713 switch_v4l2(); 727 714 f->type = t->mode; 728 - f->frequency = t->freq; 715 + f->frequency = (V4L2_TUNER_RADIO == t->mode) ? 716 + t->radio_freq : t->tv_freq; 729 717 break; 730 718 } 731 719 case VIDIOC_G_TUNER: ··· 777 763 778 764 if (V4L2_TUNER_RADIO == t->mode) { 779 765 t->audmode = tuner->audmode; 780 - set_radio_freq(client, t->freq); 766 + set_radio_freq(client, t->radio_freq); 781 767 } 782 768 break; 783 769 } ··· 805 791 struct tuner *t = i2c_get_clientdata (c); 806 792 807 793 tuner_dbg ("resume\n"); 808 - if (t->freq) 809 - set_freq(c, t->freq); 794 + if (V4L2_TUNER_RADIO == t->mode) { 795 + if (t->radio_freq) 796 + set_freq(c, t->radio_freq); 797 + } else { 798 + if (t->tv_freq) 799 + set_freq(c, t->tv_freq); 800 + } 810 801 return 0; 811 802 } 812 803
+23 -21
drivers/media/video/tuner-simple.c
··· 136 136 u8 config, tuneraddr; 137 137 u16 div; 138 138 struct tunertype *tun; 139 - unsigned char buffer[4]; 139 + u8 buffer[4]; 140 140 int rc, IFPCoff, i, j; 141 141 142 142 tun = &tuners[t->type]; ··· 146 146 if (freq > tun->params[j].ranges[i].limit) 147 147 continue; 148 148 break; 149 + } 150 + if (i == tun->params[j].count) { 151 + tuner_dbg("TV frequency out of range (%d > %d)", 152 + freq, tun->params[j].ranges[i - 1].limit); 153 + freq = tun->params[j].ranges[--i].limit; 149 154 } 150 155 config = tun->params[j].ranges[i].cb; 151 156 /* i == 0 -> VHF_LO */ ··· 244 239 break; 245 240 } 246 241 247 - /* 248 - * Philips FI1216MK2 remark from specification : 249 - * for channel selection involving band switching, and to ensure 250 - * smooth tuning to the desired channel without causing 251 - * unnecessary charge pump action, it is recommended to consider 252 - * the difference between wanted channel frequency and the 253 - * current channel frequency. Unnecessary charge pump action 254 - * will result in very low tuning voltage which may drive the 255 - * oscillator to extreme conditions. 256 - * 257 - * Progfou: specification says to send config data before 258 - * frequency in case (wanted frequency < current frequency). 259 - */ 260 - 261 242 /* IFPCoff = Video Intermediate Frequency - Vif: 262 243 940 =16*58.75 NTSC/J (Japan) 263 244 732 =16*45.75 M/N STD ··· 275 284 offset / 16, offset % 16 * 100 / 16, 276 285 div); 277 286 278 - if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) { 287 + if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) { 279 288 buffer[0] = tun->params[j].config; 280 289 buffer[1] = config; 281 290 buffer[2] = (div>>8) & 0x7f; ··· 286 295 buffer[2] = tun->params[j].config; 287 296 buffer[3] = config; 288 297 } 298 + t->last_div = div; 289 299 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", 290 300 buffer[0],buffer[1],buffer[2],buffer[3]); 291 301 ··· 329 337 { 330 338 struct tunertype *tun; 331 339 struct tuner *t = i2c_get_clientdata(c); 332 - unsigned char buffer[4]; 333 - unsigned div; 340 + u8 buffer[4]; 341 + u16 div; 334 342 int rc, j; 335 343 336 344 tun = &tuners[t->type]; ··· 366 374 } 367 375 buffer[0] = (div>>8) & 0x7f; 368 376 buffer[1] = div & 0xff; 377 + if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) { 378 + buffer[0] = buffer[2]; 379 + buffer[1] = buffer[3]; 380 + buffer[2] = (div>>8) & 0x7f; 381 + buffer[3] = div & 0xff; 382 + } else { 383 + buffer[0] = (div>>8) & 0x7f; 384 + buffer[1] = div & 0xff; 385 + } 369 386 370 387 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", 371 388 buffer[0],buffer[1],buffer[2],buffer[3]); 389 + t->last_div = div; 372 390 373 391 if (4 != (rc = i2c_master_send(c,buffer,4))) 374 392 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); ··· 392 390 t->type, tuners[t->type].name); 393 391 strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); 394 392 395 - t->tv_freq = default_set_tv_freq; 396 - t->radio_freq = default_set_radio_freq; 393 + t->set_tv_freq = default_set_tv_freq; 394 + t->set_radio_freq = default_set_radio_freq; 397 395 t->has_signal = tuner_signal; 398 - t->is_stereo = tuner_stereo; 396 + t->is_stereo = tuner_stereo; 399 397 t->standby = NULL; 400 398 401 399 return 0;
+6
drivers/media/video/tuner-types.c
··· 81 81 .ranges = tuner_philips_ntsc_ranges, 82 82 .count = ARRAY_SIZE(tuner_philips_ntsc_ranges), 83 83 .config = 0x8e, 84 + .cb_first_if_lower_freq = 1, 84 85 }, 85 86 }; 86 87 ··· 99 98 .ranges = tuner_philips_secam_ranges, 100 99 .count = ARRAY_SIZE(tuner_philips_secam_ranges), 101 100 .config = 0x8e, 101 + .cb_first_if_lower_freq = 1, 102 102 }, 103 103 }; 104 104 ··· 117 115 .ranges = tuner_philips_pal_ranges, 118 116 .count = ARRAY_SIZE(tuner_philips_pal_ranges), 119 117 .config = 0x8e, 118 + .cb_first_if_lower_freq = 1, 120 119 }, 121 120 }; 122 121 ··· 599 596 .ranges = tuner_fm1216me_mk3_pal_ranges, 600 597 .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), 601 598 .config = 0x8e, 599 + .cb_first_if_lower_freq = 1, 602 600 }, 603 601 }; 604 602 ··· 674 670 .ranges = tuner_fm1236_mk3_ntsc_ranges, 675 671 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), 676 672 .config = 0x8e, 673 + .cb_first_if_lower_freq = 1, 677 674 }, 678 675 }; 679 676 ··· 789 784 .ranges = tuner_tcl_2002n_ntsc_ranges, 790 785 .count = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges), 791 786 .config = 0x8e, 787 + .cb_first_if_lower_freq = 1, 792 788 }, 793 789 }; 794 790
+1
drivers/media/video/v4l2-common.c
··· 306 306 #endif 307 307 [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", 308 308 [_IOC_NR(AUDC_SET_INPUT)] = "AUDC_SET_INPUT", 309 + [_IOC_NR(MSP_SET_MATRIX)] = "MSP_SET_MATRIX", 309 310 310 311 [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", 311 312 [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
+18
include/media/tuner-types.h
··· 20 20 struct tuner_params { 21 21 enum param_type type; 22 22 unsigned int tda988x; 23 + /* Many Philips based tuners have a comment like this in their 24 + * datasheet: 25 + * 26 + * For channel selection involving band switching, and to ensure 27 + * smooth tuning to the desired channel without causing 28 + * unnecessary charge pump action, it is recommended to consider 29 + * the difference between wanted channel frequency and the 30 + * current channel frequency. Unnecessary charge pump action 31 + * will result in very low tuning voltage which may drive the 32 + * oscillator to extreme conditions. 33 + * 34 + * Set this flag to 1 if this tuner needs this check. 35 + * 36 + * I tested this for PAL by first setting the TV frequency to 37 + * 203 MHz and then switching to 96.6 MHz FM radio. The result was 38 + * static unless the control byte was sent first. 39 + */ 40 + unsigned int cb_first_if_lower_freq:1; 23 41 unsigned char config; /* to be moved into struct tuner_range for dvb-pll merge */ 24 42 25 43 unsigned int count;
+5 -3
include/media/tuner.h
··· 179 179 unsigned int mode; 180 180 unsigned int mode_mask; /* Combination of allowable modes */ 181 181 182 - unsigned int freq; /* keep track of the current settings */ 182 + unsigned int tv_freq; /* keep track of the current settings */ 183 + unsigned int radio_freq; 184 + u16 last_div; 183 185 unsigned int audmode; 184 186 v4l2_std_id std; 185 187 ··· 199 197 unsigned int sgIF; 200 198 201 199 /* function ptrs */ 202 - void (*tv_freq)(struct i2c_client *c, unsigned int freq); 203 - void (*radio_freq)(struct i2c_client *c, unsigned int freq); 200 + void (*set_tv_freq)(struct i2c_client *c, unsigned int freq); 201 + void (*set_radio_freq)(struct i2c_client *c, unsigned int freq); 204 202 int (*has_signal)(struct i2c_client *c); 205 203 int (*is_stereo)(struct i2c_client *c); 206 204 void (*standby)(struct i2c_client *c);
+7
include/media/v4l2-common.h
··· 120 120 /* select from TV,radio,extern,MUTE */ 121 121 #define AUDC_SET_INPUT _IOW('d',89,int) 122 122 123 + /* msp3400 ioctl: will be removed in the near future */ 124 + struct msp_matrix { 125 + int input; 126 + int output; 127 + }; 128 + #define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix) 129 + 123 130 /* tuner ioctls */ 124 131 /* Sets tuner type and its I2C addr */ 125 132 #define TUNER_SET_TYPE_ADDR _IOW('d',90,int)