aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/tda18271-fe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/tda18271-fe.c')
-rw-r--r--drivers/media/dvb/frontends/tda18271-fe.c93
1 files changed, 71 insertions, 22 deletions
diff --git a/drivers/media/dvb/frontends/tda18271-fe.c b/drivers/media/dvb/frontends/tda18271-fe.c
index e860f4c009c2..aa93e1550627 100644
--- a/drivers/media/dvb/frontends/tda18271-fe.c
+++ b/drivers/media/dvb/frontends/tda18271-fe.c
@@ -27,6 +27,9 @@ module_param_named(debug, tda18271_debug, int, 0644);
27MODULE_PARM_DESC(debug, "set debug level " 27MODULE_PARM_DESC(debug, "set debug level "
28 "(info=1, map=2, reg=4, adv=8 (or-able))"); 28 "(info=1, map=2, reg=4, adv=8 (or-able))");
29 29
30static LIST_HEAD(tda18271_list);
31static DEFINE_MUTEX(tda18271_list_mutex);
32
30/*---------------------------------------------------------------------*/ 33/*---------------------------------------------------------------------*/
31 34
32static int tda18271_ir_cal_init(struct dvb_frontend *fe) 35static int tda18271_ir_cal_init(struct dvb_frontend *fe)
@@ -936,8 +939,24 @@ fail:
936 939
937static int tda18271_release(struct dvb_frontend *fe) 940static int tda18271_release(struct dvb_frontend *fe)
938{ 941{
939 kfree(fe->tuner_priv); 942 struct tda18271_priv *priv = fe->tuner_priv;
943
944 mutex_lock(&tda18271_list_mutex);
945
946 priv->count--;
947
948 if (!priv->count) {
949 tda_dbg("destroying instance @ %d-%04x\n",
950 i2c_adapter_id(priv->i2c_adap),
951 priv->i2c_addr);
952 list_del(&priv->tda18271_list);
953
954 kfree(priv);
955 }
956 mutex_unlock(&tda18271_list_mutex);
957
940 fe->tuner_priv = NULL; 958 fe->tuner_priv = NULL;
959
941 return 0; 960 return 0;
942} 961}
943 962
@@ -1071,43 +1090,73 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1071 struct tda18271_config *cfg) 1090 struct tda18271_config *cfg)
1072{ 1091{
1073 struct tda18271_priv *priv = NULL; 1092 struct tda18271_priv *priv = NULL;
1093 int state_found = 0;
1094
1095 mutex_lock(&tda18271_list_mutex);
1096
1097 list_for_each_entry(priv, &tda18271_list, tda18271_list) {
1098 if ((i2c_adapter_id(priv->i2c_adap) == i2c_adapter_id(i2c)) &&
1099 (priv->i2c_addr == addr)) {
1100 tda_dbg("attaching existing tuner @ %d-%04x\n",
1101 i2c_adapter_id(priv->i2c_adap),
1102 priv->i2c_addr);
1103 priv->count++;
1104 fe->tuner_priv = priv;
1105 state_found = 1;
1106 /* allow dvb driver to override i2c gate setting */
1107 if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG))
1108 priv->gate = cfg->gate;
1109 break;
1110 }
1111 }
1112 if (state_found == 0) {
1113 tda_dbg("creating new tuner instance @ %d-%04x\n",
1114 i2c_adapter_id(i2c), addr);
1115
1116 priv = kzalloc(sizeof(struct tda18271_priv), GFP_KERNEL);
1117 if (priv == NULL) {
1118 mutex_unlock(&tda18271_list_mutex);
1119 return NULL;
1120 }
1074 1121
1075 priv = kzalloc(sizeof(struct tda18271_priv), GFP_KERNEL); 1122 priv->i2c_addr = addr;
1076 if (priv == NULL) 1123 priv->i2c_adap = i2c;
1077 return NULL; 1124 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
1125 priv->cal_initialized = false;
1126 mutex_init(&priv->lock);
1127 priv->count++;
1078 1128
1079 priv->i2c_addr = addr; 1129 fe->tuner_priv = priv;
1080 priv->i2c_adap = i2c;
1081 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
1082 priv->cal_initialized = false;
1083 mutex_init(&priv->lock);
1084 1130
1085 fe->tuner_priv = priv; 1131 list_add_tail(&priv->tda18271_list, &tda18271_list);
1086 1132
1087 if (tda18271_get_id(fe) < 0) 1133 if (tda18271_get_id(fe) < 0)
1088 goto fail; 1134 goto fail;
1089 1135
1090 if (tda18271_assign_map_layout(fe) < 0) 1136 if (tda18271_assign_map_layout(fe) < 0)
1091 goto fail; 1137 goto fail;
1092 1138
1093 memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops, 1139 mutex_lock(&priv->lock);
1094 sizeof(struct dvb_tuner_ops)); 1140 tda18271_init_regs(fe);
1141 mutex_unlock(&priv->lock);
1142 }
1095 1143
1096 /* override default std map with values in config struct */ 1144 /* override default std map with values in config struct */
1097 if ((cfg) && (cfg->std_map)) 1145 if ((cfg) && (cfg->std_map))
1098 tda18271_update_std_map(fe, cfg->std_map); 1146 tda18271_update_std_map(fe, cfg->std_map);
1099 1147
1100 if (tda18271_debug & DBG_MAP) 1148 mutex_unlock(&tda18271_list_mutex);
1101 tda18271_dump_std_map(fe);
1102
1103 mutex_lock(&priv->lock);
1104 1149
1105 tda18271_init_regs(fe); 1150 memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,
1151 sizeof(struct dvb_tuner_ops));
1106 1152
1107 mutex_unlock(&priv->lock); 1153 if (tda18271_debug & DBG_MAP)
1154 tda18271_dump_std_map(fe);
1108 1155
1109 return fe; 1156 return fe;
1110fail: 1157fail:
1158 mutex_unlock(&tda18271_list_mutex);
1159
1111 tda18271_release(fe); 1160 tda18271_release(fe);
1112 return NULL; 1161 return NULL;
1113} 1162}