diff options
author | Jonathan Corbet <corbet@lwn.net> | 2008-07-14 17:29:34 -0400 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2008-07-14 17:29:34 -0400 |
commit | 2fceef397f9880b212a74c418290ce69e7ac00eb (patch) | |
tree | d9cc09ab992825ef7fede4a688103503e3caf655 /drivers/media/common | |
parent | feae1ef116ed381625d3731c5ae4f4ebcb3fa302 (diff) | |
parent | bce7f793daec3e65ec5c5705d2457b81fe7b5725 (diff) |
Merge commit 'v2.6.26' into bkl-removal
Diffstat (limited to 'drivers/media/common')
-rw-r--r-- | drivers/media/common/ir-keymaps.c | 38 | ||||
-rw-r--r-- | drivers/media/common/tuners/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/common/tuners/mxl5005s.c | 4 | ||||
-rw-r--r-- | drivers/media/common/tuners/tda18271-common.c | 14 | ||||
-rw-r--r-- | drivers/media/common/tuners/tda18271-fe.c | 53 | ||||
-rw-r--r-- | drivers/media/common/tuners/tda827x.c | 4 | ||||
-rw-r--r-- | drivers/media/common/tuners/tea5761.c | 2 | ||||
-rw-r--r-- | drivers/media/common/tuners/tuner-i2c.h | 8 | ||||
-rw-r--r-- | drivers/media/common/tuners/tuner-simple.c | 6 | ||||
-rw-r--r-- | drivers/media/common/tuners/tuner-xc2028.c | 87 | ||||
-rw-r--r-- | drivers/media/common/tuners/xc5000.c | 30 | ||||
-rw-r--r-- | drivers/media/common/tuners/xc5000_priv.h | 1 |
12 files changed, 165 insertions, 83 deletions
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index a3485817e46c..8fa91f846d59 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c | |||
@@ -2201,3 +2201,41 @@ IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = { | |||
2201 | [0x25] = KEY_POWER, /* power */ | 2201 | [0x25] = KEY_POWER, /* power */ |
2202 | }; | 2202 | }; |
2203 | EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel); | 2203 | EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel); |
2204 | |||
2205 | IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = { | ||
2206 | [0x20] = KEY_LIST, | ||
2207 | [0x00] = KEY_POWER, | ||
2208 | [0x28] = KEY_1, | ||
2209 | [0x18] = KEY_2, | ||
2210 | [0x38] = KEY_3, | ||
2211 | [0x24] = KEY_4, | ||
2212 | [0x14] = KEY_5, | ||
2213 | [0x34] = KEY_6, | ||
2214 | [0x2c] = KEY_7, | ||
2215 | [0x1c] = KEY_8, | ||
2216 | [0x3c] = KEY_9, | ||
2217 | [0x12] = KEY_SUBTITLE, | ||
2218 | [0x22] = KEY_0, | ||
2219 | [0x32] = KEY_REWIND, | ||
2220 | [0x3a] = KEY_SHUFFLE, | ||
2221 | [0x02] = KEY_PRINT, | ||
2222 | [0x11] = KEY_CHANNELDOWN, | ||
2223 | [0x31] = KEY_CHANNELUP, | ||
2224 | [0x0c] = KEY_ZOOM, | ||
2225 | [0x1e] = KEY_VOLUMEDOWN, | ||
2226 | [0x3e] = KEY_VOLUMEUP, | ||
2227 | [0x0a] = KEY_MUTE, | ||
2228 | [0x04] = KEY_AUDIO, | ||
2229 | [0x26] = KEY_RECORD, | ||
2230 | [0x06] = KEY_PLAY, | ||
2231 | [0x36] = KEY_STOP, | ||
2232 | [0x16] = KEY_PAUSE, | ||
2233 | [0x2e] = KEY_REWIND, | ||
2234 | [0x0e] = KEY_FASTFORWARD, | ||
2235 | [0x30] = KEY_TEXT, | ||
2236 | [0x21] = KEY_GREEN, | ||
2237 | [0x01] = KEY_BLUE, | ||
2238 | [0x08] = KEY_EPG, | ||
2239 | [0x2a] = KEY_MENU, | ||
2240 | }; | ||
2241 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d); | ||
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index d6206540476b..85482960d012 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig | |||
@@ -21,6 +21,7 @@ config MEDIA_TUNER | |||
21 | tristate | 21 | tristate |
22 | default VIDEO_MEDIA && I2C | 22 | default VIDEO_MEDIA && I2C |
23 | depends on VIDEO_MEDIA && I2C | 23 | depends on VIDEO_MEDIA && I2C |
24 | select FW_LOADER if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG | ||
24 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG | 25 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG |
25 | select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG | 26 | select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG |
26 | select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE | 27 | select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE |
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c index 5d05b5390f66..0dc2bef9f6a3 100644 --- a/drivers/media/common/tuners/mxl5005s.c +++ b/drivers/media/common/tuners/mxl5005s.c | |||
@@ -101,7 +101,7 @@ enum { | |||
101 | MXL_QAM, | 101 | MXL_QAM, |
102 | MXL_ANALOG_CABLE, | 102 | MXL_ANALOG_CABLE, |
103 | MXL_ANALOG_OTA | 103 | MXL_ANALOG_OTA |
104 | } tuner_modu_type; | 104 | }; |
105 | 105 | ||
106 | /* MXL5005 Tuner Register Struct */ | 106 | /* MXL5005 Tuner Register Struct */ |
107 | struct TunerReg { | 107 | struct TunerReg { |
@@ -194,7 +194,7 @@ enum { | |||
194 | RFSYN_DIVM, /* 88 */ | 194 | RFSYN_DIVM, /* 88 */ |
195 | DN_BYPASS_AGC_I2C /* 89 */ | 195 | DN_BYPASS_AGC_I2C /* 89 */ |
196 | #endif | 196 | #endif |
197 | } MXL5005_ControlName; | 197 | }; |
198 | 198 | ||
199 | /* | 199 | /* |
200 | * The following context is source code provided by MaxLinear. | 200 | * The following context is source code provided by MaxLinear. |
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c index 42b5f5d4bfe6..6fb5b4586569 100644 --- a/drivers/media/common/tuners/tda18271-common.c +++ b/drivers/media/common/tuners/tda18271-common.c | |||
@@ -648,11 +648,19 @@ int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq) | |||
648 | unsigned char *regs = priv->tda18271_regs; | 648 | unsigned char *regs = priv->tda18271_regs; |
649 | u8 val; | 649 | u8 val; |
650 | 650 | ||
651 | tda18271_lookup_map(fe, RF_CAL, freq, &val); | 651 | int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val); |
652 | /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range | ||
653 | * for frequencies above 61.1 MHz. In these cases, the internal RF | ||
654 | * tracking filters calibration mechanism is used. | ||
655 | * | ||
656 | * There is no need to warn the user about this. | ||
657 | */ | ||
658 | if (ret < 0) | ||
659 | goto fail; | ||
652 | 660 | ||
653 | regs[R_EB14] = val; | 661 | regs[R_EB14] = val; |
654 | 662 | fail: | |
655 | return 0; | 663 | return ret; |
656 | } | 664 | } |
657 | 665 | ||
658 | /* | 666 | /* |
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 89c01fb1f859..93063c6fbbf6 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c | |||
@@ -45,6 +45,21 @@ static inline int charge_pump_source(struct dvb_frontend *fe, int force) | |||
45 | TDA18271_MAIN_PLL, force); | 45 | TDA18271_MAIN_PLL, force); |
46 | } | 46 | } |
47 | 47 | ||
48 | static inline void tda18271_set_if_notch(struct dvb_frontend *fe) | ||
49 | { | ||
50 | struct tda18271_priv *priv = fe->tuner_priv; | ||
51 | unsigned char *regs = priv->tda18271_regs; | ||
52 | |||
53 | switch (priv->mode) { | ||
54 | case TDA18271_ANALOG: | ||
55 | regs[R_MPD] &= ~0x80; /* IF notch = 0 */ | ||
56 | break; | ||
57 | case TDA18271_DIGITAL: | ||
58 | regs[R_MPD] |= 0x80; /* IF notch = 1 */ | ||
59 | break; | ||
60 | } | ||
61 | } | ||
62 | |||
48 | static int tda18271_channel_configuration(struct dvb_frontend *fe, | 63 | static int tda18271_channel_configuration(struct dvb_frontend *fe, |
49 | struct tda18271_std_map_item *map, | 64 | struct tda18271_std_map_item *map, |
50 | u32 freq, u32 bw) | 65 | u32 freq, u32 bw) |
@@ -60,25 +75,18 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, | |||
60 | regs[R_EP3] &= ~0x1f; /* clear std bits */ | 75 | regs[R_EP3] &= ~0x1f; /* clear std bits */ |
61 | regs[R_EP3] |= (map->agc_mode << 3) | map->std; | 76 | regs[R_EP3] |= (map->agc_mode << 3) | map->std; |
62 | 77 | ||
63 | /* set rfagc to high speed mode */ | 78 | if (priv->id == TDA18271HDC2) { |
64 | regs[R_EP3] &= ~0x04; | 79 | /* set rfagc to high speed mode */ |
80 | regs[R_EP3] &= ~0x04; | ||
81 | } | ||
65 | 82 | ||
66 | /* set cal mode to normal */ | 83 | /* set cal mode to normal */ |
67 | regs[R_EP4] &= ~0x03; | 84 | regs[R_EP4] &= ~0x03; |
68 | 85 | ||
69 | /* update IF output level & IF notch frequency */ | 86 | /* update IF output level */ |
70 | regs[R_EP4] &= ~0x1c; /* clear if level bits */ | 87 | regs[R_EP4] &= ~0x1c; /* clear if level bits */ |
71 | regs[R_EP4] |= (map->if_lvl << 2); | 88 | regs[R_EP4] |= (map->if_lvl << 2); |
72 | 89 | ||
73 | switch (priv->mode) { | ||
74 | case TDA18271_ANALOG: | ||
75 | regs[R_MPD] &= ~0x80; /* IF notch = 0 */ | ||
76 | break; | ||
77 | case TDA18271_DIGITAL: | ||
78 | regs[R_MPD] |= 0x80; /* IF notch = 1 */ | ||
79 | break; | ||
80 | } | ||
81 | |||
82 | /* update FM_RFn */ | 90 | /* update FM_RFn */ |
83 | regs[R_EP4] &= ~0x80; | 91 | regs[R_EP4] &= ~0x80; |
84 | regs[R_EP4] |= map->fm_rfn << 7; | 92 | regs[R_EP4] |= map->fm_rfn << 7; |
@@ -95,6 +103,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, | |||
95 | /* disable Power Level Indicator */ | 103 | /* disable Power Level Indicator */ |
96 | regs[R_EP1] |= 0x40; | 104 | regs[R_EP1] |= 0x40; |
97 | 105 | ||
106 | /* make sure thermometer is off */ | ||
107 | regs[R_TM] &= ~0x10; | ||
108 | |||
98 | /* frequency dependent parameters */ | 109 | /* frequency dependent parameters */ |
99 | 110 | ||
100 | tda18271_calc_ir_measure(fe, &freq); | 111 | tda18271_calc_ir_measure(fe, &freq); |
@@ -135,6 +146,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, | |||
135 | switch (priv->role) { | 146 | switch (priv->role) { |
136 | case TDA18271_MASTER: | 147 | case TDA18271_MASTER: |
137 | tda18271_calc_main_pll(fe, N); | 148 | tda18271_calc_main_pll(fe, N); |
149 | tda18271_set_if_notch(fe); | ||
138 | tda18271_write_regs(fe, R_MPD, 4); | 150 | tda18271_write_regs(fe, R_MPD, 4); |
139 | break; | 151 | break; |
140 | case TDA18271_SLAVE: | 152 | case TDA18271_SLAVE: |
@@ -142,6 +154,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, | |||
142 | tda18271_write_regs(fe, R_CPD, 4); | 154 | tda18271_write_regs(fe, R_CPD, 4); |
143 | 155 | ||
144 | regs[R_MPD] = regs[R_CPD] & 0x7f; | 156 | regs[R_MPD] = regs[R_CPD] & 0x7f; |
157 | tda18271_set_if_notch(fe); | ||
145 | tda18271_write_regs(fe, R_MPD, 1); | 158 | tda18271_write_regs(fe, R_MPD, 1); |
146 | break; | 159 | break; |
147 | } | 160 | } |
@@ -160,12 +173,14 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, | |||
160 | 173 | ||
161 | msleep(20); | 174 | msleep(20); |
162 | 175 | ||
163 | /* set rfagc to normal speed mode */ | 176 | if (priv->id == TDA18271HDC2) { |
164 | if (map->fm_rfn) | 177 | /* set rfagc to normal speed mode */ |
165 | regs[R_EP3] &= ~0x04; | 178 | if (map->fm_rfn) |
166 | else | 179 | regs[R_EP3] &= ~0x04; |
167 | regs[R_EP3] |= 0x04; | 180 | else |
168 | ret = tda18271_write_regs(fe, R_EP3, 1); | 181 | regs[R_EP3] |= 0x04; |
182 | ret = tda18271_write_regs(fe, R_EP3, 1); | ||
183 | } | ||
169 | fail: | 184 | fail: |
170 | return ret; | 185 | return ret; |
171 | } | 186 | } |
@@ -507,7 +522,7 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe) | |||
507 | /* set cal mode to normal */ | 522 | /* set cal mode to normal */ |
508 | regs[R_EP4] &= ~0x03; | 523 | regs[R_EP4] &= ~0x03; |
509 | 524 | ||
510 | /* update IF output level & IF notch frequency */ | 525 | /* update IF output level */ |
511 | regs[R_EP4] &= ~0x1c; /* clear if level bits */ | 526 | regs[R_EP4] &= ~0x1c; /* clear if level bits */ |
512 | 527 | ||
513 | ret = tda18271_write_regs(fe, R_EP3, 2); | 528 | ret = tda18271_write_regs(fe, R_EP3, 2); |
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c index d30d2c9094d9..8555d9cf9051 100644 --- a/drivers/media/common/tuners/tda827x.c +++ b/drivers/media/common/tuners/tda827x.c | |||
@@ -418,13 +418,13 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, | |||
418 | unsigned char buf[] = {0x22, 0x01}; | 418 | unsigned char buf[] = {0x22, 0x01}; |
419 | int arg; | 419 | int arg; |
420 | int gp_func; | 420 | int gp_func; |
421 | struct i2c_msg msg = { .addr = priv->cfg->switch_addr, .flags = 0, | 421 | struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) }; |
422 | .buf = buf, .len = sizeof(buf) }; | ||
423 | 422 | ||
424 | if (NULL == priv->cfg) { | 423 | if (NULL == priv->cfg) { |
425 | dprintk("tda827x_config not defined, cannot set LNA gain!\n"); | 424 | dprintk("tda827x_config not defined, cannot set LNA gain!\n"); |
426 | return; | 425 | return; |
427 | } | 426 | } |
427 | msg.addr = priv->cfg->switch_addr; | ||
428 | if (priv->cfg->config) { | 428 | if (priv->cfg->config) { |
429 | if (high) | 429 | if (high) |
430 | dprintk("setting LNA to high gain\n"); | 430 | dprintk("setting LNA to high gain\n"); |
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c index b93cdef9ac73..b23dadeecd05 100644 --- a/drivers/media/common/tuners/tea5761.c +++ b/drivers/media/common/tuners/tea5761.c | |||
@@ -295,7 +295,7 @@ struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, | |||
295 | { | 295 | { |
296 | struct tea5761_priv *priv = NULL; | 296 | struct tea5761_priv *priv = NULL; |
297 | 297 | ||
298 | if (tea5761_autodetection(i2c_adap, i2c_addr) == EINVAL) | 298 | if (tea5761_autodetection(i2c_adap, i2c_addr) != 0) |
299 | return NULL; | 299 | return NULL; |
300 | 300 | ||
301 | priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL); | 301 | priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL); |
diff --git a/drivers/media/common/tuners/tuner-i2c.h b/drivers/media/common/tuners/tuner-i2c.h index 3ad6c8e0b04c..cb1c7141f0c6 100644 --- a/drivers/media/common/tuners/tuner-i2c.h +++ b/drivers/media/common/tuners/tuner-i2c.h | |||
@@ -170,4 +170,12 @@ __fail: \ | |||
170 | __ret; \ | 170 | __ret; \ |
171 | }) | 171 | }) |
172 | 172 | ||
173 | #define hybrid_tuner_report_instance_count(state) \ | ||
174 | ({ \ | ||
175 | int __ret = 0; \ | ||
176 | if (state) \ | ||
177 | __ret = state->i2c_props.count; \ | ||
178 | __ret; \ | ||
179 | }) | ||
180 | |||
173 | #endif /* __TUNER_I2C_H__ */ | 181 | #endif /* __TUNER_I2C_H__ */ |
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index be8d903171b7..266c255cf0d8 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c | |||
@@ -1018,8 +1018,10 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | |||
1018 | fe->ops.i2c_gate_ctrl(fe, 1); | 1018 | fe->ops.i2c_gate_ctrl(fe, 1); |
1019 | 1019 | ||
1020 | if (1 != i2c_transfer(i2c_adap, &msg, 1)) | 1020 | if (1 != i2c_transfer(i2c_adap, &msg, 1)) |
1021 | tuner_warn("unable to probe %s, proceeding anyway.", | 1021 | printk(KERN_WARNING "tuner-simple %d-%04x: " |
1022 | tuners[type].name); | 1022 | "unable to probe %s, proceeding anyway.", |
1023 | i2c_adapter_id(i2c_adap), i2c_addr, | ||
1024 | tuners[type].name); | ||
1023 | 1025 | ||
1024 | if (fe->ops.i2c_gate_ctrl) | 1026 | if (fe->ops.i2c_gate_ctrl) |
1025 | fe->ops.i2c_gate_ctrl(fe, 0); | 1027 | fe->ops.i2c_gate_ctrl(fe, 0); |
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 9e9003cffc7f..0cbde17bfbb7 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -46,7 +46,7 @@ module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0); | |||
46 | MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the " | 46 | MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the " |
47 | "default firmware name\n"); | 47 | "default firmware name\n"); |
48 | 48 | ||
49 | static LIST_HEAD(xc2028_list); | 49 | static LIST_HEAD(hybrid_tuner_instance_list); |
50 | static DEFINE_MUTEX(xc2028_list_mutex); | 50 | static DEFINE_MUTEX(xc2028_list_mutex); |
51 | 51 | ||
52 | /* struct for storing firmware table */ | 52 | /* struct for storing firmware table */ |
@@ -68,12 +68,11 @@ struct firmware_properties { | |||
68 | }; | 68 | }; |
69 | 69 | ||
70 | struct xc2028_data { | 70 | struct xc2028_data { |
71 | struct list_head xc2028_list; | 71 | struct list_head hybrid_tuner_instance_list; |
72 | struct tuner_i2c_props i2c_props; | 72 | struct tuner_i2c_props i2c_props; |
73 | int (*tuner_callback) (void *dev, | 73 | int (*tuner_callback) (void *dev, |
74 | int command, int arg); | 74 | int command, int arg); |
75 | void *video_dev; | 75 | void *video_dev; |
76 | int count; | ||
77 | __u32 frequency; | 76 | __u32 frequency; |
78 | 77 | ||
79 | struct firmware_description *firm; | 78 | struct firmware_description *firm; |
@@ -1072,20 +1071,19 @@ static int xc2028_dvb_release(struct dvb_frontend *fe) | |||
1072 | 1071 | ||
1073 | mutex_lock(&xc2028_list_mutex); | 1072 | mutex_lock(&xc2028_list_mutex); |
1074 | 1073 | ||
1075 | priv->count--; | 1074 | /* only perform final cleanup if this is the last instance */ |
1076 | 1075 | if (hybrid_tuner_report_instance_count(priv) == 1) { | |
1077 | if (!priv->count) { | ||
1078 | list_del(&priv->xc2028_list); | ||
1079 | |||
1080 | kfree(priv->ctrl.fname); | 1076 | kfree(priv->ctrl.fname); |
1081 | |||
1082 | free_firmware(priv); | 1077 | free_firmware(priv); |
1083 | kfree(priv); | ||
1084 | fe->tuner_priv = NULL; | ||
1085 | } | 1078 | } |
1086 | 1079 | ||
1080 | if (priv) | ||
1081 | hybrid_tuner_release_state(priv); | ||
1082 | |||
1087 | mutex_unlock(&xc2028_list_mutex); | 1083 | mutex_unlock(&xc2028_list_mutex); |
1088 | 1084 | ||
1085 | fe->tuner_priv = NULL; | ||
1086 | |||
1089 | return 0; | 1087 | return 0; |
1090 | } | 1088 | } |
1091 | 1089 | ||
@@ -1150,7 +1148,7 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
1150 | struct xc2028_config *cfg) | 1148 | struct xc2028_config *cfg) |
1151 | { | 1149 | { |
1152 | struct xc2028_data *priv; | 1150 | struct xc2028_data *priv; |
1153 | void *video_dev; | 1151 | int instance; |
1154 | 1152 | ||
1155 | if (debug) | 1153 | if (debug) |
1156 | printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n"); | 1154 | printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n"); |
@@ -1163,48 +1161,40 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
1163 | return NULL; | 1161 | return NULL; |
1164 | } | 1162 | } |
1165 | 1163 | ||
1166 | video_dev = cfg->i2c_adap->algo_data; | ||
1167 | |||
1168 | if (debug) | ||
1169 | printk(KERN_DEBUG "xc2028: video_dev =%p\n", video_dev); | ||
1170 | |||
1171 | mutex_lock(&xc2028_list_mutex); | 1164 | mutex_lock(&xc2028_list_mutex); |
1172 | 1165 | ||
1173 | list_for_each_entry(priv, &xc2028_list, xc2028_list) { | 1166 | instance = hybrid_tuner_request_state(struct xc2028_data, priv, |
1174 | if (&priv->i2c_props.adap->dev == &cfg->i2c_adap->dev) { | 1167 | hybrid_tuner_instance_list, |
1175 | video_dev = NULL; | 1168 | cfg->i2c_adap, cfg->i2c_addr, |
1176 | if (debug) | 1169 | "xc2028"); |
1177 | printk(KERN_DEBUG "xc2028: reusing device\n"); | 1170 | switch (instance) { |
1178 | 1171 | case 0: | |
1179 | break; | 1172 | /* memory allocation failure */ |
1180 | } | 1173 | goto fail; |
1181 | } | 1174 | break; |
1182 | 1175 | case 1: | |
1183 | if (video_dev) { | 1176 | /* new tuner instance */ |
1184 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
1185 | if (priv == NULL) { | ||
1186 | mutex_unlock(&xc2028_list_mutex); | ||
1187 | return NULL; | ||
1188 | } | ||
1189 | |||
1190 | priv->i2c_props.addr = cfg->i2c_addr; | ||
1191 | priv->i2c_props.adap = cfg->i2c_adap; | ||
1192 | priv->i2c_props.name = "xc2028"; | ||
1193 | |||
1194 | priv->video_dev = video_dev; | ||
1195 | priv->tuner_callback = cfg->callback; | 1177 | priv->tuner_callback = cfg->callback; |
1196 | priv->ctrl.max_len = 13; | 1178 | priv->ctrl.max_len = 13; |
1197 | 1179 | ||
1198 | mutex_init(&priv->lock); | 1180 | mutex_init(&priv->lock); |
1199 | 1181 | ||
1200 | list_add_tail(&priv->xc2028_list, &xc2028_list); | 1182 | /* analog side (tuner-core) uses i2c_adap->algo_data. |
1201 | } | 1183 | * digital side is not guaranteed to have algo_data defined. |
1202 | 1184 | * | |
1203 | fe->tuner_priv = priv; | 1185 | * digital side will always have fe->dvb defined. |
1204 | priv->count++; | 1186 | * analog side (tuner-core) doesn't (yet) define fe->dvb. |
1187 | */ | ||
1188 | priv->video_dev = ((fe->dvb) && (fe->dvb->priv)) ? | ||
1189 | fe->dvb->priv : cfg->i2c_adap->algo_data; | ||
1205 | 1190 | ||
1206 | if (debug) | 1191 | fe->tuner_priv = priv; |
1207 | printk(KERN_DEBUG "xc2028: usage count is %i\n", priv->count); | 1192 | break; |
1193 | case 2: | ||
1194 | /* existing tuner instance */ | ||
1195 | fe->tuner_priv = priv; | ||
1196 | break; | ||
1197 | } | ||
1208 | 1198 | ||
1209 | memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops, | 1199 | memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops, |
1210 | sizeof(xc2028_dvb_tuner_ops)); | 1200 | sizeof(xc2028_dvb_tuner_ops)); |
@@ -1217,6 +1207,11 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | |||
1217 | mutex_unlock(&xc2028_list_mutex); | 1207 | mutex_unlock(&xc2028_list_mutex); |
1218 | 1208 | ||
1219 | return fe; | 1209 | return fe; |
1210 | fail: | ||
1211 | mutex_unlock(&xc2028_list_mutex); | ||
1212 | |||
1213 | xc2028_dvb_release(fe); | ||
1214 | return NULL; | ||
1220 | } | 1215 | } |
1221 | 1216 | ||
1222 | EXPORT_SYMBOL(xc2028_attach); | 1217 | EXPORT_SYMBOL(xc2028_attach); |
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index ceae6db901ec..7cf4f5bdb2ec 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -177,6 +177,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | |||
177 | {"FM Radio-INPUT1", 0x0208, 0x9002} | 177 | {"FM Radio-INPUT1", 0x0208, 0x9002} |
178 | }; | 178 | }; |
179 | 179 | ||
180 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); | ||
180 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 181 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); |
181 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 182 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); |
182 | static void xc5000_TunerReset(struct dvb_frontend *fe); | 183 | static void xc5000_TunerReset(struct dvb_frontend *fe); |
@@ -352,7 +353,7 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, | |||
352 | 353 | ||
353 | static int xc_shutdown(struct xc5000_priv *priv) | 354 | static int xc_shutdown(struct xc5000_priv *priv) |
354 | { | 355 | { |
355 | return 0; | 356 | return XC_RESULT_SUCCESS; |
356 | /* Fixme: cannot bring tuner back alive once shutdown | 357 | /* Fixme: cannot bring tuner back alive once shutdown |
357 | * without reloading the driver modules. | 358 | * without reloading the driver modules. |
358 | * return xc_write_reg(priv, XREG_POWER_DOWN, 0); | 359 | * return xc_write_reg(priv, XREG_POWER_DOWN, 0); |
@@ -685,6 +686,25 @@ static int xc5000_set_params(struct dvb_frontend *fe, | |||
685 | return 0; | 686 | return 0; |
686 | } | 687 | } |
687 | 688 | ||
689 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe) | ||
690 | { | ||
691 | struct xc5000_priv *priv = fe->tuner_priv; | ||
692 | int ret; | ||
693 | u16 id; | ||
694 | |||
695 | ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id); | ||
696 | if (ret == XC_RESULT_SUCCESS) { | ||
697 | if (id == XC_PRODUCT_ID_FW_NOT_LOADED) | ||
698 | ret = XC_RESULT_RESET_FAILURE; | ||
699 | else | ||
700 | ret = XC_RESULT_SUCCESS; | ||
701 | } | ||
702 | |||
703 | dprintk(1, "%s() returns %s id = 0x%x\n", __func__, | ||
704 | ret == XC_RESULT_SUCCESS ? "True" : "False", id); | ||
705 | return ret; | ||
706 | } | ||
707 | |||
688 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); | 708 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); |
689 | 709 | ||
690 | static int xc5000_set_analog_params(struct dvb_frontend *fe, | 710 | static int xc5000_set_analog_params(struct dvb_frontend *fe, |
@@ -693,7 +713,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, | |||
693 | struct xc5000_priv *priv = fe->tuner_priv; | 713 | struct xc5000_priv *priv = fe->tuner_priv; |
694 | int ret; | 714 | int ret; |
695 | 715 | ||
696 | if(priv->fwloaded == 0) | 716 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) |
697 | xc_load_fw_and_init_tuner(fe); | 717 | xc_load_fw_and_init_tuner(fe); |
698 | 718 | ||
699 | dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", | 719 | dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", |
@@ -808,11 +828,10 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) | |||
808 | struct xc5000_priv *priv = fe->tuner_priv; | 828 | struct xc5000_priv *priv = fe->tuner_priv; |
809 | int ret = 0; | 829 | int ret = 0; |
810 | 830 | ||
811 | if (priv->fwloaded == 0) { | 831 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { |
812 | ret = xc5000_fwupload(fe); | 832 | ret = xc5000_fwupload(fe); |
813 | if (ret != XC_RESULT_SUCCESS) | 833 | if (ret != XC_RESULT_SUCCESS) |
814 | return ret; | 834 | return ret; |
815 | priv->fwloaded = 1; | ||
816 | } | 835 | } |
817 | 836 | ||
818 | /* Start the tuner self-calibration process */ | 837 | /* Start the tuner self-calibration process */ |
@@ -852,7 +871,6 @@ static int xc5000_sleep(struct dvb_frontend *fe) | |||
852 | return -EREMOTEIO; | 871 | return -EREMOTEIO; |
853 | } | 872 | } |
854 | else { | 873 | else { |
855 | /* priv->fwloaded = 0; */ | ||
856 | return XC_RESULT_SUCCESS; | 874 | return XC_RESULT_SUCCESS; |
857 | } | 875 | } |
858 | } | 876 | } |
@@ -933,7 +951,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
933 | cfg->i2c_address); | 951 | cfg->i2c_address); |
934 | printk(KERN_INFO | 952 | printk(KERN_INFO |
935 | "xc5000: Firmware has been loaded previously\n"); | 953 | "xc5000: Firmware has been loaded previously\n"); |
936 | priv->fwloaded = 1; | ||
937 | break; | 954 | break; |
938 | case XC_PRODUCT_ID_FW_NOT_LOADED: | 955 | case XC_PRODUCT_ID_FW_NOT_LOADED: |
939 | printk(KERN_INFO | 956 | printk(KERN_INFO |
@@ -941,7 +958,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
941 | cfg->i2c_address); | 958 | cfg->i2c_address); |
942 | printk(KERN_INFO | 959 | printk(KERN_INFO |
943 | "xc5000: Firmware has not been loaded previously\n"); | 960 | "xc5000: Firmware has not been loaded previously\n"); |
944 | priv->fwloaded = 0; | ||
945 | break; | 961 | break; |
946 | default: | 962 | default: |
947 | printk(KERN_ERR | 963 | printk(KERN_ERR |
diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h index ecebfe4745ad..a72a9887fe7f 100644 --- a/drivers/media/common/tuners/xc5000_priv.h +++ b/drivers/media/common/tuners/xc5000_priv.h | |||
@@ -30,7 +30,6 @@ struct xc5000_priv { | |||
30 | u32 bandwidth; | 30 | u32 bandwidth; |
31 | u8 video_standard; | 31 | u8 video_standard; |
32 | u8 rf_mode; | 32 | u8 rf_mode; |
33 | u8 fwloaded; | ||
34 | 33 | ||
35 | void *devptr; | 34 | void *devptr; |
36 | }; | 35 | }; |