diff options
| author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-01-15 18:31:10 -0500 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-01-15 18:31:10 -0500 |
| commit | 21e2379b9ef705fcb3ba3be738decd3397fc30b7 (patch) | |
| tree | 6e4f5334547aa538150fe52b60bfe014425eb53b | |
| parent | d04ae27bae42bcce1b3fa70ca2edf25d92b1cf39 (diff) | |
| parent | 366cc64b0d9ac922ac4f0f54e06c13ec95249928 (diff) | |
Merge branch 'work'
| -rw-r--r-- | drivers/media/dvb/frontends/dvb-pll.c | 2 | ||||
| -rw-r--r-- | drivers/media/video/cx88/cx88-alsa.c | 4 | ||||
| -rw-r--r-- | drivers/media/video/em28xx/em28xx-input.c | 77 | ||||
| -rw-r--r-- | drivers/media/video/msp3400-driver.c | 4 | ||||
| -rw-r--r-- | drivers/media/video/msp3400.h | 8 | ||||
| -rw-r--r-- | drivers/media/video/mt20xx.c | 12 | ||||
| -rw-r--r-- | drivers/media/video/tda8290.c | 4 | ||||
| -rw-r--r-- | drivers/media/video/tea5767.c | 18 | ||||
| -rw-r--r-- | drivers/media/video/tuner-core.c | 85 | ||||
| -rw-r--r-- | drivers/media/video/tuner-simple.c | 44 | ||||
| -rw-r--r-- | drivers/media/video/tuner-types.c | 6 | ||||
| -rw-r--r-- | drivers/media/video/v4l2-common.c | 1 | ||||
| -rw-r--r-- | include/media/tuner-types.h | 20 | ||||
| -rw-r--r-- | include/media/tuner.h | 8 | ||||
| -rw-r--r-- | include/media/v4l2-common.h | 7 |
15 files changed, 212 insertions, 88 deletions
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 757075f007c1..1b9934ea5b06 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
| @@ -333,7 +333,7 @@ struct dvb_pll_desc dvb_pll_tbmv30111in = { | |||
| 333 | .name = "Samsung TBMV30111IN", | 333 | .name = "Samsung TBMV30111IN", |
| 334 | .min = 54000000, | 334 | .min = 54000000, |
| 335 | .max = 860000000, | 335 | .max = 860000000, |
| 336 | .count = 4, | 336 | .count = 6, |
| 337 | .entries = { | 337 | .entries = { |
| 338 | { 172000000, 44000000, 166666, 0xb4, 0x01 }, | 338 | { 172000000, 44000000, 166666, 0xb4, 0x01 }, |
| 339 | { 214000000, 44000000, 166666, 0xb4, 0x02 }, | 339 | { 214000000, 44000000, 166666, 0xb4, 0x02 }, |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index e649f678d47a..a2e36a1e5f59 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
| @@ -333,10 +333,10 @@ static snd_pcm_hardware_t snd_cx88_digital_hw = { | |||
| 333 | .channels_min = 1, | 333 | .channels_min = 1, |
| 334 | .channels_max = 2, | 334 | .channels_max = 2, |
| 335 | .buffer_bytes_max = (2*2048), | 335 | .buffer_bytes_max = (2*2048), |
| 336 | .period_bytes_min = 256, | 336 | .period_bytes_min = 2048, |
| 337 | .period_bytes_max = 2048, | 337 | .period_bytes_max = 2048, |
| 338 | .periods_min = 2, | 338 | .periods_min = 2, |
| 339 | .periods_max = 16, | 339 | .periods_max = 2, |
| 340 | }; | 340 | }; |
| 341 | 341 | ||
| 342 | /* | 342 | /* |
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 9b94f77d6fd7..30dfa5370c73 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
| @@ -76,6 +76,58 @@ static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { | |||
| 76 | [ 0x40 ] = KEY_ZOOM, | 76 | [ 0x40 ] = KEY_ZOOM, |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | static IR_KEYTAB_TYPE ir_codes_em_pinnacle_usb[IR_KEYTAB_SIZE] = { | ||
| 80 | [ 0x3a ] = KEY_KP0, | ||
| 81 | [ 0x31 ] = KEY_KP1, | ||
| 82 | [ 0x32 ] = KEY_KP2, | ||
| 83 | [ 0x33 ] = KEY_KP3, | ||
| 84 | [ 0x34 ] = KEY_KP4, | ||
| 85 | [ 0x35 ] = KEY_KP5, | ||
| 86 | [ 0x36 ] = KEY_KP6, | ||
| 87 | [ 0x37 ] = KEY_KP7, | ||
| 88 | [ 0x38 ] = KEY_KP8, | ||
| 89 | [ 0x39 ] = KEY_KP9, | ||
| 90 | |||
| 91 | [ 0x2f ] = KEY_POWER, | ||
| 92 | |||
| 93 | [ 0x2e ] = KEY_P, | ||
| 94 | [ 0x1f ] = KEY_L, | ||
| 95 | [ 0x2b ] = KEY_I, | ||
| 96 | |||
| 97 | [ 0x2d ] = KEY_ZOOM, | ||
| 98 | [ 0x1e ] = KEY_ZOOM, | ||
| 99 | [ 0x1b ] = KEY_VOLUMEUP, | ||
| 100 | [ 0x0f ] = KEY_VOLUMEDOWN, | ||
| 101 | [ 0x17 ] = KEY_CHANNELUP, | ||
| 102 | [ 0x1c ] = KEY_CHANNELDOWN, | ||
| 103 | [ 0x25 ] = KEY_INFO, | ||
| 104 | |||
| 105 | [ 0x3c ] = KEY_MUTE, | ||
| 106 | |||
| 107 | [ 0x3d ] = KEY_LEFT, | ||
| 108 | [ 0x3b ] = KEY_RIGHT, | ||
| 109 | |||
| 110 | [ 0x3f ] = KEY_UP, | ||
| 111 | [ 0x3e ] = KEY_DOWN, | ||
| 112 | [ 0x1a ] = KEY_PAUSE, | ||
| 113 | |||
| 114 | [ 0x1d ] = KEY_MENU, | ||
| 115 | [ 0x19 ] = KEY_PLAY, | ||
| 116 | [ 0x16 ] = KEY_REWIND, | ||
| 117 | [ 0x13 ] = KEY_FORWARD, | ||
| 118 | [ 0x15 ] = KEY_PAUSE, | ||
| 119 | [ 0x0e ] = KEY_REWIND, | ||
| 120 | [ 0x0d ] = KEY_PLAY, | ||
| 121 | [ 0x0b ] = KEY_STOP, | ||
| 122 | [ 0x07 ] = KEY_FORWARD, | ||
| 123 | [ 0x27 ] = KEY_RECORD, | ||
| 124 | [ 0x26 ] = KEY_TUNER, | ||
| 125 | [ 0x29 ] = KEY_TEXT, | ||
| 126 | [ 0x2a ] = KEY_MEDIA, | ||
| 127 | [ 0x18 ] = KEY_EPG, | ||
| 128 | [ 0x27 ] = KEY_RECORD, | ||
| 129 | }; | ||
| 130 | |||
| 79 | /* ----------------------------------------------------------------------- */ | 131 | /* ----------------------------------------------------------------------- */ |
| 80 | 132 | ||
| 81 | static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 133 | static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
| @@ -138,6 +190,28 @@ static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
| 138 | return 1; | 190 | return 1; |
| 139 | } | 191 | } |
| 140 | 192 | ||
| 193 | static int get_key_pinnacle_usb(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
| 194 | { | ||
| 195 | unsigned char buf[3]; | ||
| 196 | |||
| 197 | /* poll IR chip */ | ||
| 198 | |||
| 199 | if (3 != i2c_master_recv(&ir->c,buf,3)) { | ||
| 200 | dprintk("read error\n"); | ||
| 201 | return -EIO; | ||
| 202 | } | ||
| 203 | |||
| 204 | dprintk("key %02x\n", buf[2]&0x3f); | ||
| 205 | if (buf[0]!=0x00){ | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | *ir_key = buf[2]&0x3f; | ||
| 210 | *ir_raw = buf[2]&0x3f; | ||
| 211 | |||
| 212 | return 1; | ||
| 213 | } | ||
| 214 | |||
| 141 | /* ----------------------------------------------------------------------- */ | 215 | /* ----------------------------------------------------------------------- */ |
| 142 | void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir) | 216 | void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir) |
| 143 | { | 217 | { |
| @@ -159,6 +233,9 @@ void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir) | |||
| 159 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); | 233 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); |
| 160 | break; | 234 | break; |
| 161 | case (EM2820_BOARD_PINNACLE_USB_2): | 235 | case (EM2820_BOARD_PINNACLE_USB_2): |
| 236 | ir->ir_codes = ir_codes_em_pinnacle_usb; | ||
| 237 | ir->get_key = get_key_pinnacle_usb; | ||
| 238 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Pinnacle PCTV)"); | ||
| 162 | break; | 239 | break; |
| 163 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): | 240 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): |
| 164 | ir->ir_codes = ir_codes_hauppauge_new; | 241 | ir->ir_codes = ir_codes_hauppauge_new; |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 09ff25b554b6..69ed369c2f48 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
| @@ -1031,8 +1031,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 1031 | } | 1031 | } |
| 1032 | 1032 | ||
| 1033 | default: | 1033 | default: |
| 1034 | /* nothing */ | 1034 | /* unknown */ |
| 1035 | break; | 1035 | return -EINVAL; |
| 1036 | } | 1036 | } |
| 1037 | return 0; | 1037 | return 0; |
| 1038 | } | 1038 | } |
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h index 70a5ef8ba017..a9ac57d0700b 100644 --- a/drivers/media/video/msp3400.h +++ b/drivers/media/video/msp3400.h | |||
| @@ -6,14 +6,6 @@ | |||
| 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 | /* This macro is allowed for *constants* only, gcc must calculate it | 9 | /* This macro is allowed for *constants* only, gcc must calculate it |
| 18 | at compile time. Remember -- no floats in kernel mode */ | 10 | at compile time. Remember -- no floats in kernel mode */ |
| 19 | #define MSP_CARRIER(freq) ((int)((float)(freq / 18.432) * (1 << 24))) | 11 | #define MSP_CARRIER(freq) ((int)((float)(freq / 18.432) * (1 << 24))) |
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c index 0bf1caac5887..c7c9f3f8715c 100644 --- a/drivers/media/video/mt20xx.c +++ b/drivers/media/video/mt20xx.c | |||
| @@ -353,8 +353,8 @@ static int mt2032_init(struct i2c_client *c) | |||
| 353 | } while (xok != 1 ); | 353 | } while (xok != 1 ); |
| 354 | t->xogc=xogc; | 354 | t->xogc=xogc; |
| 355 | 355 | ||
| 356 | t->tv_freq = mt2032_set_tv_freq; | 356 | t->set_tv_freq = mt2032_set_tv_freq; |
| 357 | t->radio_freq = mt2032_set_radio_freq; | 357 | t->set_radio_freq = mt2032_set_radio_freq; |
| 358 | return(1); | 358 | return(1); |
| 359 | } | 359 | } |
| 360 | 360 | ||
| @@ -481,8 +481,8 @@ static int mt2050_init(struct i2c_client *c) | |||
| 481 | i2c_master_recv(c,buf,1); | 481 | i2c_master_recv(c,buf,1); |
| 482 | 482 | ||
| 483 | tuner_dbg("mt2050: sro is %x\n",buf[0]); | 483 | tuner_dbg("mt2050: sro is %x\n",buf[0]); |
| 484 | t->tv_freq = mt2050_set_tv_freq; | 484 | t->set_tv_freq = mt2050_set_tv_freq; |
| 485 | t->radio_freq = mt2050_set_radio_freq; | 485 | t->set_radio_freq = mt2050_set_radio_freq; |
| 486 | return 0; | 486 | return 0; |
| 487 | } | 487 | } |
| 488 | 488 | ||
| @@ -494,8 +494,8 @@ int microtune_init(struct i2c_client *c) | |||
| 494 | int company_code; | 494 | int company_code; |
| 495 | 495 | ||
| 496 | memset(buf,0,sizeof(buf)); | 496 | memset(buf,0,sizeof(buf)); |
| 497 | t->tv_freq = NULL; | 497 | t->set_tv_freq = NULL; |
| 498 | t->radio_freq = NULL; | 498 | t->set_radio_freq = NULL; |
| 499 | t->standby = NULL; | 499 | t->standby = NULL; |
| 500 | if (t->std & V4L2_STD_525_60) { | 500 | if (t->std & V4L2_STD_525_60) { |
| 501 | tuner_dbg("pinnacle ntsc\n"); | 501 | tuner_dbg("pinnacle ntsc\n"); |
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index 2498b76df429..7b4fb282ac82 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
| @@ -567,8 +567,8 @@ int tda8290_init(struct i2c_client *c) | |||
| 567 | } | 567 | } |
| 568 | tuner_info("tuner: type set to %s\n", c->name); | 568 | tuner_info("tuner: type set to %s\n", c->name); |
| 569 | 569 | ||
| 570 | t->tv_freq = set_tv_freq; | 570 | t->set_tv_freq = set_tv_freq; |
| 571 | t->radio_freq = set_radio_freq; | 571 | t->set_radio_freq = set_radio_freq; |
| 572 | t->has_signal = has_signal; | 572 | t->has_signal = has_signal; |
| 573 | t->standby = standby; | 573 | t->standby = standby; |
| 574 | t->tda827x_lpsel = 0; | 574 | t->tda827x_lpsel = 0; |
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c index 921fe72f23d5..c2b98f81c192 100644 --- a/drivers/media/video/tea5767.c +++ b/drivers/media/video/tea5767.c | |||
| @@ -62,7 +62,7 @@ extern int tuner_debug; | |||
| 62 | 62 | ||
| 63 | #define TEA5767_PORT1_HIGH 0x01 | 63 | #define TEA5767_PORT1_HIGH 0x01 |
| 64 | 64 | ||
| 65 | /* Forth register */ | 65 | /* Fourth register */ |
| 66 | #define TEA5767_PORT2_HIGH 0x80 | 66 | #define TEA5767_PORT2_HIGH 0x80 |
| 67 | /* Chips stops working. Only I2C bus remains on */ | 67 | /* Chips stops working. Only I2C bus remains on */ |
| 68 | #define TEA5767_STDBY 0x40 | 68 | #define TEA5767_STDBY 0x40 |
| @@ -85,7 +85,7 @@ extern int tuner_debug; | |||
| 85 | /* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */ | 85 | /* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */ |
| 86 | #define TEA5767_SRCH_IND 0x01 | 86 | #define TEA5767_SRCH_IND 0x01 |
| 87 | 87 | ||
| 88 | /* Fiveth register */ | 88 | /* Fifth register */ |
| 89 | 89 | ||
| 90 | /* By activating, it will use Xtal at 13 MHz as reference for divider */ | 90 | /* By activating, it will use Xtal at 13 MHz as reference for divider */ |
| 91 | #define TEA5767_PLLREF_ENABLE 0x80 | 91 | #define TEA5767_PLLREF_ENABLE 0x80 |
| @@ -109,13 +109,13 @@ extern int tuner_debug; | |||
| 109 | #define TEA5767_STEREO_MASK 0x80 | 109 | #define TEA5767_STEREO_MASK 0x80 |
| 110 | #define TEA5767_IF_CNTR_MASK 0x7f | 110 | #define TEA5767_IF_CNTR_MASK 0x7f |
| 111 | 111 | ||
| 112 | /* Four register */ | 112 | /* Fourth register */ |
| 113 | #define TEA5767_ADC_LEVEL_MASK 0xf0 | 113 | #define TEA5767_ADC_LEVEL_MASK 0xf0 |
| 114 | 114 | ||
| 115 | /* should be 0 */ | 115 | /* should be 0 */ |
| 116 | #define TEA5767_CHIP_ID_MASK 0x0f | 116 | #define TEA5767_CHIP_ID_MASK 0x0f |
| 117 | 117 | ||
| 118 | /* Fiveth register */ | 118 | /* Fifth register */ |
| 119 | /* Reserved for future extensions */ | 119 | /* Reserved for future extensions */ |
| 120 | #define TEA5767_RESERVED_MASK 0xff | 120 | #define TEA5767_RESERVED_MASK 0xff |
| 121 | 121 | ||
| @@ -220,19 +220,19 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq) | |||
| 220 | tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); | 220 | tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); |
| 221 | buffer[2] |= TEA5767_HIGH_LO_INJECT; | 221 | buffer[2] |= TEA5767_HIGH_LO_INJECT; |
| 222 | buffer[4] |= TEA5767_PLLREF_ENABLE; | 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 | break; | 224 | break; |
| 225 | case TEA5767_LOW_LO_13MHz: | 225 | case TEA5767_LOW_LO_13MHz: |
| 226 | tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); | 226 | tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); |
| 227 | 227 | ||
| 228 | buffer[4] |= TEA5767_PLLREF_ENABLE; | 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 | break; | 230 | break; |
| 231 | case TEA5767_LOW_LO_32768: | 231 | case TEA5767_LOW_LO_32768: |
| 232 | tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); | 232 | tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); |
| 233 | buffer[3] |= TEA5767_XTAL_32768; | 233 | buffer[3] |= TEA5767_XTAL_32768; |
| 234 | /* const 700=4000*175 Khz - to adjust freq to right value */ | 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 | break; | 236 | break; |
| 237 | case TEA5767_HIGH_LO_32768: | 237 | case TEA5767_HIGH_LO_32768: |
| 238 | default: | 238 | default: |
| @@ -350,8 +350,8 @@ int tea5767_tuner_init(struct i2c_client *c) | |||
| 350 | tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio"); | 350 | tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio"); |
| 351 | strlcpy(c->name, "tea5767", sizeof(c->name)); | 351 | strlcpy(c->name, "tea5767", sizeof(c->name)); |
| 352 | 352 | ||
| 353 | t->tv_freq = set_tv_freq; | 353 | t->set_tv_freq = set_tv_freq; |
| 354 | t->radio_freq = set_radio_freq; | 354 | t->set_radio_freq = set_radio_freq; |
| 355 | t->has_signal = tea5767_signal; | 355 | t->has_signal = tea5767_signal; |
| 356 | t->is_stereo = tea5767_stereo; | 356 | t->is_stereo = tea5767_stereo; |
| 357 | t->standby = tea5767_standby; | 357 | t->standby = tea5767_standby; |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index f30ef79d795e..2995b22acb43 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
| @@ -82,7 +82,7 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 82 | tuner_warn ("tuner type not set\n"); | 82 | tuner_warn ("tuner type not set\n"); |
| 83 | return; | 83 | return; |
| 84 | } | 84 | } |
| 85 | if (NULL == t->tv_freq) { | 85 | if (NULL == t->set_tv_freq) { |
| 86 | tuner_warn ("Tuner has no way to set tv freq\n"); | 86 | tuner_warn ("Tuner has no way to set tv freq\n"); |
| 87 | return; | 87 | return; |
| 88 | } | 88 | } |
| @@ -90,8 +90,14 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 90 | tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n", | 90 | tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n", |
| 91 | freq / 16, freq % 16 * 100 / 16, tv_range[0], | 91 | freq / 16, freq % 16 * 100 / 16, tv_range[0], |
| 92 | tv_range[1]); | 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 | static void set_radio_freq(struct i2c_client *c, unsigned int freq) | 103 | static void set_radio_freq(struct i2c_client *c, unsigned int freq) |
| @@ -102,18 +108,23 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
| 102 | tuner_warn ("tuner type not set\n"); | 108 | tuner_warn ("tuner type not set\n"); |
| 103 | return; | 109 | return; |
| 104 | } | 110 | } |
| 105 | if (NULL == t->radio_freq) { | 111 | if (NULL == t->set_radio_freq) { |
| 106 | tuner_warn ("tuner has no way to set radio frequency\n"); | 112 | tuner_warn ("tuner has no way to set radio frequency\n"); |
| 107 | return; | 113 | return; |
| 108 | } | 114 | } |
| 109 | if (freq <= radio_range[0] * 16000 || freq >= radio_range[1] * 16000) { | 115 | if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) { |
| 110 | tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n", | 116 | tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n", |
| 111 | freq / 16000, freq % 16000 * 100 / 16000, | 117 | freq / 16000, freq % 16000 * 100 / 16000, |
| 112 | radio_range[0], radio_range[1]); | 118 | radio_range[0], radio_range[1]); |
| 119 | /* V4L2 spec: if the freq is not possible then the closest | ||
| 120 | possible value should be selected */ | ||
| 121 | if (freq < radio_range[0] * 16000) | ||
| 122 | freq = radio_range[0] * 16000; | ||
| 123 | else | ||
| 124 | freq = radio_range[1] * 16000; | ||
| 113 | } | 125 | } |
| 114 | 126 | ||
| 115 | t->radio_freq(c, freq); | 127 | t->set_radio_freq(c, freq); |
| 116 | return; | ||
| 117 | } | 128 | } |
| 118 | 129 | ||
| 119 | static void set_freq(struct i2c_client *c, unsigned long freq) | 130 | static void set_freq(struct i2c_client *c, unsigned long freq) |
| @@ -125,15 +136,16 @@ static void set_freq(struct i2c_client *c, unsigned long freq) | |||
| 125 | tuner_dbg("radio freq set to %lu.%02lu\n", | 136 | tuner_dbg("radio freq set to %lu.%02lu\n", |
| 126 | freq / 16000, freq % 16000 * 100 / 16000); | 137 | freq / 16000, freq % 16000 * 100 / 16000); |
| 127 | set_radio_freq(c, freq); | 138 | set_radio_freq(c, freq); |
| 139 | t->radio_freq = freq; | ||
| 128 | break; | 140 | break; |
| 129 | case V4L2_TUNER_ANALOG_TV: | 141 | case V4L2_TUNER_ANALOG_TV: |
| 130 | case V4L2_TUNER_DIGITAL_TV: | 142 | case V4L2_TUNER_DIGITAL_TV: |
| 131 | tuner_dbg("tv freq set to %lu.%02lu\n", | 143 | tuner_dbg("tv freq set to %lu.%02lu\n", |
| 132 | freq / 16, freq % 16 * 100 / 16); | 144 | freq / 16, freq % 16 * 100 / 16); |
| 133 | set_tv_freq(c, freq); | 145 | set_tv_freq(c, freq); |
| 146 | t->tv_freq = freq; | ||
| 134 | break; | 147 | break; |
| 135 | } | 148 | } |
| 136 | t->freq = freq; | ||
| 137 | } | 149 | } |
| 138 | 150 | ||
| 139 | static void set_type(struct i2c_client *c, unsigned int type, | 151 | static void set_type(struct i2c_client *c, unsigned int type, |
| @@ -212,7 +224,7 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
| 212 | if (t->mode_mask == T_UNINITIALIZED) | 224 | if (t->mode_mask == T_UNINITIALIZED) |
| 213 | t->mode_mask = new_mode_mask; | 225 | t->mode_mask = new_mode_mask; |
| 214 | 226 | ||
| 215 | set_freq(c, t->freq); | 227 | set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? t->radio_freq : t->tv_freq); |
| 216 | tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", | 228 | tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", |
| 217 | c->adapter->name, c->driver->driver.name, c->addr << 1, type, | 229 | c->adapter->name, c->driver->driver.name, c->addr << 1, type, |
| 218 | t->mode_mask); | 230 | t->mode_mask); |
| @@ -377,11 +389,11 @@ static void tuner_status(struct i2c_client *client) | |||
| 377 | default: p = "undefined"; break; | 389 | default: p = "undefined"; break; |
| 378 | } | 390 | } |
| 379 | if (t->mode == V4L2_TUNER_RADIO) { | 391 | if (t->mode == V4L2_TUNER_RADIO) { |
| 380 | freq = t->freq / 16000; | 392 | freq = t->radio_freq / 16000; |
| 381 | freq_fraction = (t->freq % 16000) * 100 / 16000; | 393 | freq_fraction = (t->radio_freq % 16000) * 100 / 16000; |
| 382 | } else { | 394 | } else { |
| 383 | freq = t->freq / 16; | 395 | freq = t->tv_freq / 16; |
| 384 | freq_fraction = (t->freq % 16) * 100 / 16; | 396 | freq_fraction = (t->tv_freq % 16) * 100 / 16; |
| 385 | } | 397 | } |
| 386 | tuner_info("Tuner mode: %s\n", p); | 398 | tuner_info("Tuner mode: %s\n", p); |
| 387 | tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); | 399 | tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); |
| @@ -456,7 +468,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
| 456 | t->type = TUNER_TEA5767; | 468 | t->type = TUNER_TEA5767; |
| 457 | t->mode_mask = T_RADIO; | 469 | t->mode_mask = T_RADIO; |
| 458 | t->mode = T_STANDBY; | 470 | t->mode = T_STANDBY; |
| 459 | t->freq = 87.5 * 16; /* Sets freq to FM range */ | 471 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ |
| 460 | default_mode_mask &= ~T_RADIO; | 472 | default_mode_mask &= ~T_RADIO; |
| 461 | 473 | ||
| 462 | goto register_client; | 474 | goto register_client; |
| @@ -469,7 +481,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
| 469 | if (default_mode_mask != T_UNINITIALIZED) { | 481 | if (default_mode_mask != T_UNINITIALIZED) { |
| 470 | tuner_dbg ("Setting mode_mask to 0x%02x\n", default_mode_mask); | 482 | tuner_dbg ("Setting mode_mask to 0x%02x\n", default_mode_mask); |
| 471 | t->mode_mask = default_mode_mask; | 483 | t->mode_mask = default_mode_mask; |
| 472 | t->freq = 400 * 16; /* Sets freq to VHF High */ | 484 | t->tv_freq = 400 * 16; /* Sets freq to VHF High */ |
| 485 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ | ||
| 473 | default_mode_mask = T_UNINITIALIZED; | 486 | default_mode_mask = T_UNINITIALIZED; |
| 474 | } | 487 | } |
| 475 | 488 | ||
| @@ -565,16 +578,18 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 565 | set_addr(client, (struct tuner_setup *)arg); | 578 | set_addr(client, (struct tuner_setup *)arg); |
| 566 | break; | 579 | break; |
| 567 | case AUDC_SET_RADIO: | 580 | case AUDC_SET_RADIO: |
| 568 | set_mode(client,t,V4L2_TUNER_RADIO, "AUDC_SET_RADIO"); | 581 | if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO") |
| 582 | == EINVAL) | ||
| 583 | return 0; | ||
| 584 | if (t->radio_freq) | ||
| 585 | set_freq(client, t->radio_freq); | ||
| 569 | break; | 586 | break; |
| 570 | case TUNER_SET_STANDBY: | 587 | case TUNER_SET_STANDBY: |
| 571 | { | 588 | if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) |
| 572 | if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) | 589 | return 0; |
| 573 | return 0; | 590 | if (t->standby) |
| 574 | if (t->standby) | 591 | t->standby (client); |
| 575 | t->standby (client); | 592 | break; |
| 576 | break; | ||
| 577 | } | ||
| 578 | case VIDIOCSAUDIO: | 593 | case VIDIOCSAUDIO: |
| 579 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) | 594 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) |
| 580 | return 0; | 595 | return 0; |
| @@ -583,7 +598,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 583 | 598 | ||
| 584 | /* Should be implemented, since bttv calls it */ | 599 | /* Should be implemented, since bttv calls it */ |
| 585 | tuner_dbg("VIDIOCSAUDIO not implemented.\n"); | 600 | tuner_dbg("VIDIOCSAUDIO not implemented.\n"); |
| 586 | |||
| 587 | break; | 601 | break; |
| 588 | /* --- v4l ioctls --- */ | 602 | /* --- v4l ioctls --- */ |
| 589 | /* take care: bttv does userspace copying, we'll get a | 603 | /* take care: bttv does userspace copying, we'll get a |
| @@ -609,8 +623,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 609 | if (vc->norm < ARRAY_SIZE(map)) | 623 | if (vc->norm < ARRAY_SIZE(map)) |
| 610 | t->std = map[vc->norm]; | 624 | t->std = map[vc->norm]; |
| 611 | tuner_fixup_std(t); | 625 | tuner_fixup_std(t); |
| 612 | if (t->freq) | 626 | if (t->tv_freq) |
| 613 | set_tv_freq(client, t->freq); | 627 | set_tv_freq(client, t->tv_freq); |
| 614 | return 0; | 628 | return 0; |
| 615 | } | 629 | } |
| 616 | case VIDIOCSFREQ: | 630 | case VIDIOCSFREQ: |
| @@ -684,15 +698,14 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 684 | 698 | ||
| 685 | t->std = *id; | 699 | t->std = *id; |
| 686 | tuner_fixup_std(t); | 700 | tuner_fixup_std(t); |
| 687 | if (t->freq) | 701 | if (t->tv_freq) |
| 688 | set_freq(client, t->freq); | 702 | set_freq(client, t->tv_freq); |
| 689 | break; | 703 | break; |
| 690 | } | 704 | } |
| 691 | case VIDIOC_S_FREQUENCY: | 705 | case VIDIOC_S_FREQUENCY: |
| 692 | { | 706 | { |
| 693 | struct v4l2_frequency *f = arg; | 707 | struct v4l2_frequency *f = arg; |
| 694 | 708 | ||
| 695 | t->freq = f->frequency; | ||
| 696 | switch_v4l2(); | 709 | switch_v4l2(); |
| 697 | if (V4L2_TUNER_RADIO == f->type && | 710 | if (V4L2_TUNER_RADIO == f->type && |
| 698 | V4L2_TUNER_RADIO != t->mode) { | 711 | V4L2_TUNER_RADIO != t->mode) { |
| @@ -700,7 +713,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 700 | == EINVAL) | 713 | == EINVAL) |
| 701 | return 0; | 714 | return 0; |
| 702 | } | 715 | } |
| 703 | set_freq(client,t->freq); | 716 | set_freq(client,f->frequency); |
| 704 | 717 | ||
| 705 | break; | 718 | break; |
| 706 | } | 719 | } |
| @@ -712,7 +725,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 712 | return 0; | 725 | return 0; |
| 713 | switch_v4l2(); | 726 | switch_v4l2(); |
| 714 | f->type = t->mode; | 727 | f->type = t->mode; |
| 715 | f->frequency = t->freq; | 728 | f->frequency = (V4L2_TUNER_RADIO == t->mode) ? |
| 729 | t->radio_freq : t->tv_freq; | ||
| 716 | break; | 730 | break; |
| 717 | } | 731 | } |
| 718 | case VIDIOC_G_TUNER: | 732 | case VIDIOC_G_TUNER: |
| @@ -763,7 +777,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
| 763 | 777 | ||
| 764 | if (V4L2_TUNER_RADIO == t->mode) { | 778 | if (V4L2_TUNER_RADIO == t->mode) { |
| 765 | t->audmode = tuner->audmode; | 779 | t->audmode = tuner->audmode; |
| 766 | set_radio_freq(client, t->freq); | 780 | set_radio_freq(client, t->radio_freq); |
| 767 | } | 781 | } |
| 768 | break; | 782 | break; |
| 769 | } | 783 | } |
| @@ -791,8 +805,13 @@ static int tuner_resume(struct device *dev) | |||
| 791 | struct tuner *t = i2c_get_clientdata (c); | 805 | struct tuner *t = i2c_get_clientdata (c); |
| 792 | 806 | ||
| 793 | tuner_dbg ("resume\n"); | 807 | tuner_dbg ("resume\n"); |
| 794 | if (t->freq) | 808 | if (V4L2_TUNER_RADIO == t->mode) { |
| 795 | set_freq(c, t->freq); | 809 | if (t->radio_freq) |
| 810 | set_freq(c, t->radio_freq); | ||
| 811 | } else { | ||
| 812 | if (t->tv_freq) | ||
| 813 | set_freq(c, t->tv_freq); | ||
| 814 | } | ||
| 796 | return 0; | 815 | return 0; |
| 797 | } | 816 | } |
| 798 | 817 | ||
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 3879262cf4ca..37977ff49780 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
| @@ -136,7 +136,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 136 | u8 config, tuneraddr; | 136 | u8 config, tuneraddr; |
| 137 | u16 div; | 137 | u16 div; |
| 138 | struct tunertype *tun; | 138 | struct tunertype *tun; |
| 139 | unsigned char buffer[4]; | 139 | u8 buffer[4]; |
| 140 | int rc, IFPCoff, i, j; | 140 | int rc, IFPCoff, i, j; |
| 141 | 141 | ||
| 142 | tun = &tuners[t->type]; | 142 | tun = &tuners[t->type]; |
| @@ -147,6 +147,11 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 147 | continue; | 147 | continue; |
| 148 | break; | 148 | break; |
| 149 | } | 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; | ||
| 154 | } | ||
| 150 | config = tun->params[j].ranges[i].cb; | 155 | config = tun->params[j].ranges[i].cb; |
| 151 | /* i == 0 -> VHF_LO */ | 156 | /* i == 0 -> VHF_LO */ |
| 152 | /* i == 1 -> VHF_HI */ | 157 | /* i == 1 -> VHF_HI */ |
| @@ -239,20 +244,6 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 239 | break; | 244 | break; |
| 240 | } | 245 | } |
| 241 | 246 | ||
| 242 | /* | ||
| 243 | * Philips FI1216MK2 remark from specification : | ||
| 244 | * for channel selection involving band switching, and to ensure | ||
| 245 | * smooth tuning to the desired channel without causing | ||
| 246 | * unnecessary charge pump action, it is recommended to consider | ||
| 247 | * the difference between wanted channel frequency and the | ||
| 248 | * current channel frequency. Unnecessary charge pump action | ||
| 249 | * will result in very low tuning voltage which may drive the | ||
| 250 | * oscillator to extreme conditions. | ||
| 251 | * | ||
| 252 | * Progfou: specification says to send config data before | ||
| 253 | * frequency in case (wanted frequency < current frequency). | ||
| 254 | */ | ||
| 255 | |||
| 256 | /* IFPCoff = Video Intermediate Frequency - Vif: | 247 | /* IFPCoff = Video Intermediate Frequency - Vif: |
| 257 | 940 =16*58.75 NTSC/J (Japan) | 248 | 940 =16*58.75 NTSC/J (Japan) |
| 258 | 732 =16*45.75 M/N STD | 249 | 732 =16*45.75 M/N STD |
| @@ -284,7 +275,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 284 | offset / 16, offset % 16 * 100 / 16, | 275 | offset / 16, offset % 16 * 100 / 16, |
| 285 | div); | 276 | div); |
| 286 | 277 | ||
| 287 | if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) { | 278 | if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) { |
| 288 | buffer[0] = tun->params[j].config; | 279 | buffer[0] = tun->params[j].config; |
| 289 | buffer[1] = config; | 280 | buffer[1] = config; |
| 290 | buffer[2] = (div>>8) & 0x7f; | 281 | buffer[2] = (div>>8) & 0x7f; |
| @@ -295,6 +286,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
| 295 | buffer[2] = tun->params[j].config; | 286 | buffer[2] = tun->params[j].config; |
| 296 | buffer[3] = config; | 287 | buffer[3] = config; |
| 297 | } | 288 | } |
| 289 | t->last_div = div; | ||
| 298 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | 290 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", |
| 299 | buffer[0],buffer[1],buffer[2],buffer[3]); | 291 | buffer[0],buffer[1],buffer[2],buffer[3]); |
| 300 | 292 | ||
| @@ -337,8 +329,8 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
| 337 | { | 329 | { |
| 338 | struct tunertype *tun; | 330 | struct tunertype *tun; |
| 339 | struct tuner *t = i2c_get_clientdata(c); | 331 | struct tuner *t = i2c_get_clientdata(c); |
| 340 | unsigned char buffer[4]; | 332 | u8 buffer[4]; |
| 341 | unsigned div; | 333 | u16 div; |
| 342 | int rc, j; | 334 | int rc, j; |
| 343 | 335 | ||
| 344 | tun = &tuners[t->type]; | 336 | tun = &tuners[t->type]; |
| @@ -374,9 +366,19 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
| 374 | } | 366 | } |
| 375 | buffer[0] = (div>>8) & 0x7f; | 367 | buffer[0] = (div>>8) & 0x7f; |
| 376 | buffer[1] = div & 0xff; | 368 | buffer[1] = div & 0xff; |
| 369 | if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) { | ||
| 370 | buffer[0] = buffer[2]; | ||
| 371 | buffer[1] = buffer[3]; | ||
| 372 | buffer[2] = (div>>8) & 0x7f; | ||
| 373 | buffer[3] = div & 0xff; | ||
| 374 | } else { | ||
| 375 | buffer[0] = (div>>8) & 0x7f; | ||
| 376 | buffer[1] = div & 0xff; | ||
| 377 | } | ||
| 377 | 378 | ||
| 378 | tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", | 379 | tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", |
| 379 | buffer[0],buffer[1],buffer[2],buffer[3]); | 380 | buffer[0],buffer[1],buffer[2],buffer[3]); |
| 381 | t->last_div = div; | ||
| 380 | 382 | ||
| 381 | if (4 != (rc = i2c_master_send(c,buffer,4))) | 383 | if (4 != (rc = i2c_master_send(c,buffer,4))) |
| 382 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | 384 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); |
| @@ -390,10 +392,10 @@ int default_tuner_init(struct i2c_client *c) | |||
| 390 | t->type, tuners[t->type].name); | 392 | t->type, tuners[t->type].name); |
| 391 | strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); | 393 | strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); |
| 392 | 394 | ||
| 393 | t->tv_freq = default_set_tv_freq; | 395 | t->set_tv_freq = default_set_tv_freq; |
| 394 | t->radio_freq = default_set_radio_freq; | 396 | t->set_radio_freq = default_set_radio_freq; |
| 395 | t->has_signal = tuner_signal; | 397 | t->has_signal = tuner_signal; |
| 396 | t->is_stereo = tuner_stereo; | 398 | t->is_stereo = tuner_stereo; |
| 397 | t->standby = NULL; | 399 | t->standby = NULL; |
| 398 | 400 | ||
| 399 | return 0; | 401 | return 0; |
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index 32c9be4c5ca6..6fe781798d89 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c | |||
| @@ -81,6 +81,7 @@ static struct tuner_params tuner_philips_ntsc_params[] = { | |||
| 81 | .ranges = tuner_philips_ntsc_ranges, | 81 | .ranges = tuner_philips_ntsc_ranges, |
| 82 | .count = ARRAY_SIZE(tuner_philips_ntsc_ranges), | 82 | .count = ARRAY_SIZE(tuner_philips_ntsc_ranges), |
| 83 | .config = 0x8e, | 83 | .config = 0x8e, |
| 84 | .cb_first_if_lower_freq = 1, | ||
| 84 | }, | 85 | }, |
| 85 | }; | 86 | }; |
| 86 | 87 | ||
| @@ -98,6 +99,7 @@ static struct tuner_params tuner_philips_secam_params[] = { | |||
| 98 | .ranges = tuner_philips_secam_ranges, | 99 | .ranges = tuner_philips_secam_ranges, |
| 99 | .count = ARRAY_SIZE(tuner_philips_secam_ranges), | 100 | .count = ARRAY_SIZE(tuner_philips_secam_ranges), |
| 100 | .config = 0x8e, | 101 | .config = 0x8e, |
| 102 | .cb_first_if_lower_freq = 1, | ||
| 101 | }, | 103 | }, |
| 102 | }; | 104 | }; |
| 103 | 105 | ||
| @@ -115,6 +117,7 @@ static struct tuner_params tuner_philips_pal_params[] = { | |||
| 115 | .ranges = tuner_philips_pal_ranges, | 117 | .ranges = tuner_philips_pal_ranges, |
| 116 | .count = ARRAY_SIZE(tuner_philips_pal_ranges), | 118 | .count = ARRAY_SIZE(tuner_philips_pal_ranges), |
| 117 | .config = 0x8e, | 119 | .config = 0x8e, |
| 120 | .cb_first_if_lower_freq = 1, | ||
| 118 | }, | 121 | }, |
| 119 | }; | 122 | }; |
| 120 | 123 | ||
| @@ -596,6 +599,7 @@ static struct tuner_params tuner_fm1216me_mk3_params[] = { | |||
| 596 | .ranges = tuner_fm1216me_mk3_pal_ranges, | 599 | .ranges = tuner_fm1216me_mk3_pal_ranges, |
| 597 | .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), | 600 | .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), |
| 598 | .config = 0x8e, | 601 | .config = 0x8e, |
| 602 | .cb_first_if_lower_freq = 1, | ||
| 599 | }, | 603 | }, |
| 600 | }; | 604 | }; |
| 601 | 605 | ||
| @@ -670,6 +674,7 @@ static struct tuner_params tuner_fm1236_mk3_params[] = { | |||
| 670 | .ranges = tuner_fm1236_mk3_ntsc_ranges, | 674 | .ranges = tuner_fm1236_mk3_ntsc_ranges, |
| 671 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), | 675 | .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), |
| 672 | .config = 0x8e, | 676 | .config = 0x8e, |
| 677 | .cb_first_if_lower_freq = 1, | ||
| 673 | }, | 678 | }, |
| 674 | }; | 679 | }; |
| 675 | 680 | ||
| @@ -784,6 +789,7 @@ static struct tuner_params tuner_tcl_2002n_params[] = { | |||
| 784 | .ranges = tuner_tcl_2002n_ntsc_ranges, | 789 | .ranges = tuner_tcl_2002n_ntsc_ranges, |
| 785 | .count = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges), | 790 | .count = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges), |
| 786 | .config = 0x8e, | 791 | .config = 0x8e, |
| 792 | .cb_first_if_lower_freq = 1, | ||
| 787 | }, | 793 | }, |
| 788 | }; | 794 | }; |
| 789 | 795 | ||
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 5dbd7c1b362a..cd2c4475525e 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
| @@ -306,6 +306,7 @@ static const char *v4l2_int_ioctls[] = { | |||
| 306 | #endif | 306 | #endif |
| 307 | [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", | 307 | [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", |
| 308 | [_IOC_NR(AUDC_SET_INPUT)] = "AUDC_SET_INPUT", | 308 | [_IOC_NR(AUDC_SET_INPUT)] = "AUDC_SET_INPUT", |
| 309 | [_IOC_NR(MSP_SET_MATRIX)] = "MSP_SET_MATRIX", | ||
| 309 | 310 | ||
| 310 | [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", | 311 | [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", |
| 311 | [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", | 312 | [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", |
diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h index 64b16b1f1926..15821ab14a9e 100644 --- a/include/media/tuner-types.h +++ b/include/media/tuner-types.h | |||
| @@ -19,6 +19,25 @@ struct tuner_range { | |||
| 19 | 19 | ||
| 20 | struct tuner_params { | 20 | struct tuner_params { |
| 21 | enum param_type type; | 21 | enum param_type type; |
| 22 | /* Many Philips based tuners have a comment like this in their | ||
| 23 | * datasheet: | ||
| 24 | * | ||
| 25 | * For channel selection involving band switching, and to ensure | ||
| 26 | * smooth tuning to the desired channel without causing | ||
| 27 | * unnecessary charge pump action, it is recommended to consider | ||
| 28 | * the difference between wanted channel frequency and the | ||
| 29 | * current channel frequency. Unnecessary charge pump action | ||
| 30 | * will result in very low tuning voltage which may drive the | ||
| 31 | * oscillator to extreme conditions. | ||
| 32 | * | ||
| 33 | * Set cb_first_if_lower_freq to 1, if this check is | ||
| 34 | * required for this tuner. | ||
| 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; | ||
| 22 | unsigned char config; /* to be moved into struct tuner_range for dvb-pll merge */ | 41 | unsigned char config; /* to be moved into struct tuner_range for dvb-pll merge */ |
| 23 | 42 | ||
| 24 | unsigned int count; | 43 | unsigned int count; |
| @@ -27,7 +46,6 @@ struct tuner_params { | |||
| 27 | 46 | ||
| 28 | struct tunertype { | 47 | struct tunertype { |
| 29 | char *name; | 48 | char *name; |
| 30 | unsigned int has_tda988x:1; | ||
| 31 | struct tuner_params *params; | 49 | struct tuner_params *params; |
| 32 | }; | 50 | }; |
| 33 | 51 | ||
diff --git a/include/media/tuner.h b/include/media/tuner.h index a1d63787bc08..a5beeac495c7 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h | |||
| @@ -179,7 +179,9 @@ struct tuner { | |||
| 179 | unsigned int mode; | 179 | unsigned int mode; |
| 180 | unsigned int mode_mask; /* Combination of allowable modes */ | 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 | unsigned int audmode; | 185 | unsigned int audmode; |
| 184 | v4l2_std_id std; | 186 | v4l2_std_id std; |
| 185 | 187 | ||
| @@ -197,8 +199,8 @@ struct tuner { | |||
| 197 | unsigned int sgIF; | 199 | unsigned int sgIF; |
| 198 | 200 | ||
| 199 | /* function ptrs */ | 201 | /* function ptrs */ |
| 200 | void (*tv_freq)(struct i2c_client *c, unsigned int freq); | 202 | void (*set_tv_freq)(struct i2c_client *c, unsigned int freq); |
| 201 | void (*radio_freq)(struct i2c_client *c, unsigned int freq); | 203 | void (*set_radio_freq)(struct i2c_client *c, unsigned int freq); |
| 202 | int (*has_signal)(struct i2c_client *c); | 204 | int (*has_signal)(struct i2c_client *c); |
| 203 | int (*is_stereo)(struct i2c_client *c); | 205 | int (*is_stereo)(struct i2c_client *c); |
| 204 | void (*standby)(struct i2c_client *c); | 206 | void (*standby)(struct i2c_client *c); |
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index c74052abb189..d4030a7e16e0 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h | |||
| @@ -120,6 +120,13 @@ enum v4l2_chip_ident { | |||
| 120 | /* select from TV,radio,extern,MUTE */ | 120 | /* select from TV,radio,extern,MUTE */ |
| 121 | #define AUDC_SET_INPUT _IOW('d',89,int) | 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 | /* tuner ioctls */ | 130 | /* tuner ioctls */ |
| 124 | /* Sets tuner type and its I2C addr */ | 131 | /* Sets tuner type and its I2C addr */ |
| 125 | #define TUNER_SET_TYPE_ADDR _IOW('d',90,int) | 132 | #define TUNER_SET_TYPE_ADDR _IOW('d',90,int) |
