aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c178
1 files changed, 129 insertions, 49 deletions
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index b5ee3ebfcfca..9638a69f36b2 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -90,11 +90,22 @@ struct firmware_properties {
90 int scode_nr; 90 int scode_nr;
91}; 91};
92 92
93enum xc2028_state {
94 XC2028_NO_FIRMWARE = 0,
95 XC2028_WAITING_FIRMWARE,
96 XC2028_ACTIVE,
97 XC2028_SLEEP,
98 XC2028_NODEV,
99};
100
93struct xc2028_data { 101struct xc2028_data {
94 struct list_head hybrid_tuner_instance_list; 102 struct list_head hybrid_tuner_instance_list;
95 struct tuner_i2c_props i2c_props; 103 struct tuner_i2c_props i2c_props;
96 __u32 frequency; 104 __u32 frequency;
97 105
106 enum xc2028_state state;
107 const char *fname;
108
98 struct firmware_description *firm; 109 struct firmware_description *firm;
99 int firm_size; 110 int firm_size;
100 __u16 firm_version; 111 __u16 firm_version;
@@ -255,6 +266,21 @@ static v4l2_std_id parse_audio_std_option(void)
255 return 0; 266 return 0;
256} 267}
257 268
269static int check_device_status(struct xc2028_data *priv)
270{
271 switch (priv->state) {
272 case XC2028_NO_FIRMWARE:
273 case XC2028_WAITING_FIRMWARE:
274 return -EAGAIN;
275 case XC2028_ACTIVE:
276 case XC2028_SLEEP:
277 return 0;
278 case XC2028_NODEV:
279 return -ENODEV;
280 }
281 return 0;
282}
283
258static void free_firmware(struct xc2028_data *priv) 284static void free_firmware(struct xc2028_data *priv)
259{ 285{
260 int i; 286 int i;
@@ -270,45 +296,28 @@ static void free_firmware(struct xc2028_data *priv)
270 296
271 priv->firm = NULL; 297 priv->firm = NULL;
272 priv->firm_size = 0; 298 priv->firm_size = 0;
299 priv->state = XC2028_NO_FIRMWARE;
273 300
274 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); 301 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
275} 302}
276 303
277static int load_all_firmwares(struct dvb_frontend *fe) 304static int load_all_firmwares(struct dvb_frontend *fe,
305 const struct firmware *fw)
278{ 306{
279 struct xc2028_data *priv = fe->tuner_priv; 307 struct xc2028_data *priv = fe->tuner_priv;
280 const struct firmware *fw = NULL;
281 const unsigned char *p, *endp; 308 const unsigned char *p, *endp;
282 int rc = 0; 309 int rc = 0;
283 int n, n_array; 310 int n, n_array;
284 char name[33]; 311 char name[33];
285 char *fname;
286 312
287 tuner_dbg("%s called\n", __func__); 313 tuner_dbg("%s called\n", __func__);
288 314
289 if (!firmware_name[0])
290 fname = priv->ctrl.fname;
291 else
292 fname = firmware_name;
293
294 tuner_dbg("Reading firmware %s\n", fname);
295 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
296 if (rc < 0) {
297 if (rc == -ENOENT)
298 tuner_err("Error: firmware %s not found.\n",
299 fname);
300 else
301 tuner_err("Error %d while requesting firmware %s \n",
302 rc, fname);
303
304 return rc;
305 }
306 p = fw->data; 315 p = fw->data;
307 endp = p + fw->size; 316 endp = p + fw->size;
308 317
309 if (fw->size < sizeof(name) - 1 + 2 + 2) { 318 if (fw->size < sizeof(name) - 1 + 2 + 2) {
310 tuner_err("Error: firmware file %s has invalid size!\n", 319 tuner_err("Error: firmware file %s has invalid size!\n",
311 fname); 320 priv->fname);
312 goto corrupt; 321 goto corrupt;
313 } 322 }
314 323
@@ -323,7 +332,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
323 p += 2; 332 p += 2;
324 333
325 tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n", 334 tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
326 n_array, fname, name, 335 n_array, priv->fname, name,
327 priv->firm_version >> 8, priv->firm_version & 0xff); 336 priv->firm_version >> 8, priv->firm_version & 0xff);
328 337
329 priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL); 338 priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL);
@@ -417,9 +426,10 @@ err:
417 free_firmware(priv); 426 free_firmware(priv);
418 427
419done: 428done:
420 release_firmware(fw);
421 if (rc == 0) 429 if (rc == 0)
422 tuner_dbg("Firmware files loaded.\n"); 430 tuner_dbg("Firmware files loaded.\n");
431 else
432 priv->state = XC2028_NODEV;
423 433
424 return rc; 434 return rc;
425} 435}
@@ -707,22 +717,15 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
707{ 717{
708 struct xc2028_data *priv = fe->tuner_priv; 718 struct xc2028_data *priv = fe->tuner_priv;
709 struct firmware_properties new_fw; 719 struct firmware_properties new_fw;
710 int rc = 0, retry_count = 0; 720 int rc, retry_count = 0;
711 u16 version, hwmodel; 721 u16 version, hwmodel;
712 v4l2_std_id std0; 722 v4l2_std_id std0;
713 723
714 tuner_dbg("%s called\n", __func__); 724 tuner_dbg("%s called\n", __func__);
715 725
716 if (!priv->firm) { 726 rc = check_device_status(priv);
717 if (!priv->ctrl.fname) { 727 if (rc < 0)
718 tuner_info("xc2028/3028 firmware name not set!\n"); 728 return rc;
719 return -EINVAL;
720 }
721
722 rc = load_all_firmwares(fe);
723 if (rc < 0)
724 return rc;
725 }
726 729
727 if (priv->ctrl.mts && !(type & FM)) 730 if (priv->ctrl.mts && !(type & FM))
728 type |= MTS; 731 type |= MTS;
@@ -749,9 +752,13 @@ retry:
749 printk("scode_nr %d\n", new_fw.scode_nr); 752 printk("scode_nr %d\n", new_fw.scode_nr);
750 } 753 }
751 754
752 /* No need to reload base firmware if it matches */ 755 /*
753 if (((BASE | new_fw.type) & BASE_TYPES) == 756 * No need to reload base firmware if it matches and if the tuner
754 (priv->cur_fw.type & BASE_TYPES)) { 757 * is not at sleep mode
758 */
759 if ((priv->state = XC2028_ACTIVE) &&
760 (((BASE | new_fw.type) & BASE_TYPES) ==
761 (priv->cur_fw.type & BASE_TYPES))) {
755 tuner_dbg("BASE firmware not changed.\n"); 762 tuner_dbg("BASE firmware not changed.\n");
756 goto skip_base; 763 goto skip_base;
757 } 764 }
@@ -872,10 +879,13 @@ read_not_reliable:
872 * 2. Tell whether BASE firmware was just changed the next time through. 879 * 2. Tell whether BASE firmware was just changed the next time through.
873 */ 880 */
874 priv->cur_fw.type |= BASE; 881 priv->cur_fw.type |= BASE;
882 priv->state = XC2028_ACTIVE;
875 883
876 return 0; 884 return 0;
877 885
878fail: 886fail:
887 priv->state = XC2028_SLEEP;
888
879 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); 889 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
880 if (retry_count < 8) { 890 if (retry_count < 8) {
881 msleep(50); 891 msleep(50);
@@ -897,6 +907,10 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
897 907
898 tuner_dbg("%s called\n", __func__); 908 tuner_dbg("%s called\n", __func__);
899 909
910 rc = check_device_status(priv);
911 if (rc < 0)
912 return rc;
913
900 mutex_lock(&priv->lock); 914 mutex_lock(&priv->lock);
901 915
902 /* Sync Lock Indicator */ 916 /* Sync Lock Indicator */
@@ -1111,11 +1125,16 @@ static int xc2028_set_params(struct dvb_frontend *fe)
1111 u32 delsys = c->delivery_system; 1125 u32 delsys = c->delivery_system;
1112 u32 bw = c->bandwidth_hz; 1126 u32 bw = c->bandwidth_hz;
1113 struct xc2028_data *priv = fe->tuner_priv; 1127 struct xc2028_data *priv = fe->tuner_priv;
1114 unsigned int type=0; 1128 int rc;
1129 unsigned int type = 0;
1115 u16 demod = 0; 1130 u16 demod = 0;
1116 1131
1117 tuner_dbg("%s called\n", __func__); 1132 tuner_dbg("%s called\n", __func__);
1118 1133
1134 rc = check_device_status(priv);
1135 if (rc < 0)
1136 return rc;
1137
1119 switch (delsys) { 1138 switch (delsys) {
1120 case SYS_DVBT: 1139 case SYS_DVBT:
1121 case SYS_DVBT2: 1140 case SYS_DVBT2:
@@ -1201,7 +1220,11 @@ static int xc2028_set_params(struct dvb_frontend *fe)
1201static int xc2028_sleep(struct dvb_frontend *fe) 1220static int xc2028_sleep(struct dvb_frontend *fe)
1202{ 1221{
1203 struct xc2028_data *priv = fe->tuner_priv; 1222 struct xc2028_data *priv = fe->tuner_priv;
1204 int rc = 0; 1223 int rc;
1224
1225 rc = check_device_status(priv);
1226 if (rc < 0)
1227 return rc;
1205 1228
1206 /* Avoid firmware reload on slow devices or if PM disabled */ 1229 /* Avoid firmware reload on slow devices or if PM disabled */
1207 if (no_poweroff || priv->ctrl.disable_power_mgmt) 1230 if (no_poweroff || priv->ctrl.disable_power_mgmt)
@@ -1220,7 +1243,7 @@ static int xc2028_sleep(struct dvb_frontend *fe)
1220 else 1243 else
1221 rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00}); 1244 rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00});
1222 1245
1223 priv->cur_fw.type = 0; /* need firmware reload */ 1246 priv->state = XC2028_SLEEP;
1224 1247
1225 mutex_unlock(&priv->lock); 1248 mutex_unlock(&priv->lock);
1226 1249
@@ -1237,8 +1260,9 @@ static int xc2028_dvb_release(struct dvb_frontend *fe)
1237 1260
1238 /* only perform final cleanup if this is the last instance */ 1261 /* only perform final cleanup if this is the last instance */
1239 if (hybrid_tuner_report_instance_count(priv) == 1) { 1262 if (hybrid_tuner_report_instance_count(priv) == 1) {
1240 kfree(priv->ctrl.fname);
1241 free_firmware(priv); 1263 free_firmware(priv);
1264 kfree(priv->ctrl.fname);
1265 priv->ctrl.fname = NULL;
1242 } 1266 }
1243 1267
1244 if (priv) 1268 if (priv)
@@ -1254,14 +1278,42 @@ static int xc2028_dvb_release(struct dvb_frontend *fe)
1254static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency) 1278static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1255{ 1279{
1256 struct xc2028_data *priv = fe->tuner_priv; 1280 struct xc2028_data *priv = fe->tuner_priv;
1281 int rc;
1257 1282
1258 tuner_dbg("%s called\n", __func__); 1283 tuner_dbg("%s called\n", __func__);
1259 1284
1285 rc = check_device_status(priv);
1286 if (rc < 0)
1287 return rc;
1288
1260 *frequency = priv->frequency; 1289 *frequency = priv->frequency;
1261 1290
1262 return 0; 1291 return 0;
1263} 1292}
1264 1293
1294static void load_firmware_cb(const struct firmware *fw,
1295 void *context)
1296{
1297 struct dvb_frontend *fe = context;
1298 struct xc2028_data *priv = fe->tuner_priv;
1299 int rc;
1300
1301 tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error");
1302 if (!fw) {
1303 tuner_err("Could not load firmware %s.\n", priv->fname);
1304 priv->state = XC2028_NODEV;
1305 return;
1306 }
1307
1308 rc = load_all_firmwares(fe, fw);
1309
1310 release_firmware(fw);
1311
1312 if (rc < 0)
1313 return;
1314 priv->state = XC2028_SLEEP;
1315}
1316
1265static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) 1317static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
1266{ 1318{
1267 struct xc2028_data *priv = fe->tuner_priv; 1319 struct xc2028_data *priv = fe->tuner_priv;
@@ -1272,21 +1324,49 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
1272 1324
1273 mutex_lock(&priv->lock); 1325 mutex_lock(&priv->lock);
1274 1326
1327 /*
1328 * Copy the config data.
1329 * For the firmware name, keep a local copy of the string,
1330 * in order to avoid troubles during device release.
1331 */
1332 if (priv->ctrl.fname)
1333 kfree(priv->ctrl.fname);
1275 memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); 1334 memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
1276 if (priv->ctrl.max_len < 9)
1277 priv->ctrl.max_len = 13;
1278
1279 if (p->fname) { 1335 if (p->fname) {
1280 if (priv->ctrl.fname && strcmp(p->fname, priv->ctrl.fname)) {
1281 kfree(priv->ctrl.fname);
1282 free_firmware(priv);
1283 }
1284
1285 priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); 1336 priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
1286 if (priv->ctrl.fname == NULL) 1337 if (priv->ctrl.fname == NULL)
1287 rc = -ENOMEM; 1338 rc = -ENOMEM;
1288 } 1339 }
1289 1340
1341 /*
1342 * If firmware name changed, frees firmware. As free_firmware will
1343 * reset the status to NO_FIRMWARE, this forces a new request_firmware
1344 */
1345 if (!firmware_name[0] && p->fname &&
1346 priv->fname && strcmp(p->fname, priv->fname))
1347 free_firmware(priv);
1348
1349 if (priv->ctrl.max_len < 9)
1350 priv->ctrl.max_len = 13;
1351
1352 if (priv->state == XC2028_NO_FIRMWARE) {
1353 if (!firmware_name[0])
1354 priv->fname = priv->ctrl.fname;
1355 else
1356 priv->fname = firmware_name;
1357
1358 rc = request_firmware_nowait(THIS_MODULE, 1,
1359 priv->fname,
1360 priv->i2c_props.adap->dev.parent,
1361 GFP_KERNEL,
1362 fe, load_firmware_cb);
1363 if (rc < 0) {
1364 tuner_err("Failed to request firmware %s\n",
1365 priv->fname);
1366 priv->state = XC2028_NODEV;
1367 }
1368 priv->state = XC2028_WAITING_FIRMWARE;
1369 }
1290 mutex_unlock(&priv->lock); 1370 mutex_unlock(&priv->lock);
1291 1371
1292 return rc; 1372 return rc;