diff options
author | Michael Krufky <mkrufky@linuxtv.org> | 2008-04-22 13:41:54 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 12:42:26 -0400 |
commit | f9e315a16a5536120bac09a6d4217b8381c73c5c (patch) | |
tree | 31993e21297805eaf5405d4f54b982e2874af9f3 /drivers | |
parent | 2756665c28a7d2e25d92745195b5171866e12da9 (diff) |
V4L/DVB (7136): tda18271: use hybrid_tuner_request_state to manage tuner instances
Convert tda18271 to use the new hybrid_tuner_request_state and
hybrid_tuner_release_state macros to manage state sharing between
hybrid tuner instances.
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/dvb/frontends/tda18271-common.c | 19 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda18271-fe.c | 66 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda18271-priv.h | 7 |
3 files changed, 37 insertions, 55 deletions
diff --git a/drivers/media/dvb/frontends/tda18271-common.c b/drivers/media/dvb/frontends/tda18271-common.c index bca57099061..39496463ccf 100644 --- a/drivers/media/dvb/frontends/tda18271-common.c +++ b/drivers/media/dvb/frontends/tda18271-common.c | |||
@@ -125,16 +125,16 @@ int tda18271_read_regs(struct dvb_frontend *fe) | |||
125 | unsigned char buf = 0x00; | 125 | unsigned char buf = 0x00; |
126 | int ret; | 126 | int ret; |
127 | struct i2c_msg msg[] = { | 127 | struct i2c_msg msg[] = { |
128 | { .addr = priv->i2c_addr, .flags = 0, | 128 | { .addr = priv->i2c_props.addr, .flags = 0, |
129 | .buf = &buf, .len = 1 }, | 129 | .buf = &buf, .len = 1 }, |
130 | { .addr = priv->i2c_addr, .flags = I2C_M_RD, | 130 | { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, |
131 | .buf = regs, .len = 16 } | 131 | .buf = regs, .len = 16 } |
132 | }; | 132 | }; |
133 | 133 | ||
134 | tda18271_i2c_gate_ctrl(fe, 1); | 134 | tda18271_i2c_gate_ctrl(fe, 1); |
135 | 135 | ||
136 | /* read all registers */ | 136 | /* read all registers */ |
137 | ret = i2c_transfer(priv->i2c_adap, msg, 2); | 137 | ret = i2c_transfer(priv->i2c_props.adap, msg, 2); |
138 | 138 | ||
139 | tda18271_i2c_gate_ctrl(fe, 0); | 139 | tda18271_i2c_gate_ctrl(fe, 0); |
140 | 140 | ||
@@ -155,16 +155,16 @@ int tda18271_read_extended(struct dvb_frontend *fe) | |||
155 | unsigned char buf = 0x00; | 155 | unsigned char buf = 0x00; |
156 | int ret, i; | 156 | int ret, i; |
157 | struct i2c_msg msg[] = { | 157 | struct i2c_msg msg[] = { |
158 | { .addr = priv->i2c_addr, .flags = 0, | 158 | { .addr = priv->i2c_props.addr, .flags = 0, |
159 | .buf = &buf, .len = 1 }, | 159 | .buf = &buf, .len = 1 }, |
160 | { .addr = priv->i2c_addr, .flags = I2C_M_RD, | 160 | { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, |
161 | .buf = regdump, .len = TDA18271_NUM_REGS } | 161 | .buf = regdump, .len = TDA18271_NUM_REGS } |
162 | }; | 162 | }; |
163 | 163 | ||
164 | tda18271_i2c_gate_ctrl(fe, 1); | 164 | tda18271_i2c_gate_ctrl(fe, 1); |
165 | 165 | ||
166 | /* read all registers */ | 166 | /* read all registers */ |
167 | ret = i2c_transfer(priv->i2c_adap, msg, 2); | 167 | ret = i2c_transfer(priv->i2c_props.adap, msg, 2); |
168 | 168 | ||
169 | tda18271_i2c_gate_ctrl(fe, 0); | 169 | tda18271_i2c_gate_ctrl(fe, 0); |
170 | 170 | ||
@@ -192,7 +192,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) | |||
192 | struct tda18271_priv *priv = fe->tuner_priv; | 192 | struct tda18271_priv *priv = fe->tuner_priv; |
193 | unsigned char *regs = priv->tda18271_regs; | 193 | unsigned char *regs = priv->tda18271_regs; |
194 | unsigned char buf[TDA18271_NUM_REGS + 1]; | 194 | unsigned char buf[TDA18271_NUM_REGS + 1]; |
195 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 195 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0, |
196 | .buf = buf, .len = len + 1 }; | 196 | .buf = buf, .len = len + 1 }; |
197 | int i, ret; | 197 | int i, ret; |
198 | 198 | ||
@@ -205,7 +205,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) | |||
205 | tda18271_i2c_gate_ctrl(fe, 1); | 205 | tda18271_i2c_gate_ctrl(fe, 1); |
206 | 206 | ||
207 | /* write registers */ | 207 | /* write registers */ |
208 | ret = i2c_transfer(priv->i2c_adap, &msg, 1); | 208 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); |
209 | 209 | ||
210 | tda18271_i2c_gate_ctrl(fe, 0); | 210 | tda18271_i2c_gate_ctrl(fe, 0); |
211 | 211 | ||
@@ -223,7 +223,8 @@ int tda18271_init_regs(struct dvb_frontend *fe) | |||
223 | unsigned char *regs = priv->tda18271_regs; | 223 | unsigned char *regs = priv->tda18271_regs; |
224 | 224 | ||
225 | tda_dbg("initializing registers for device @ %d-%04x\n", | 225 | tda_dbg("initializing registers for device @ %d-%04x\n", |
226 | i2c_adapter_id(priv->i2c_adap), priv->i2c_addr); | 226 | i2c_adapter_id(priv->i2c_props.adap), |
227 | priv->i2c_props.addr); | ||
227 | 228 | ||
228 | /* initialize registers */ | 229 | /* initialize registers */ |
229 | switch (priv->id) { | 230 | switch (priv->id) { |
diff --git a/drivers/media/dvb/frontends/tda18271-fe.c b/drivers/media/dvb/frontends/tda18271-fe.c index dfe72aaec38..7f7fab7cd5a 100644 --- a/drivers/media/dvb/frontends/tda18271-fe.c +++ b/drivers/media/dvb/frontends/tda18271-fe.c | |||
@@ -31,8 +31,8 @@ static int tda18271_cal_on_startup; | |||
31 | module_param_named(cal, tda18271_cal_on_startup, int, 0644); | 31 | module_param_named(cal, tda18271_cal_on_startup, int, 0644); |
32 | MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup"); | 32 | MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup"); |
33 | 33 | ||
34 | static LIST_HEAD(tda18271_list); | ||
35 | static DEFINE_MUTEX(tda18271_list_mutex); | 34 | static DEFINE_MUTEX(tda18271_list_mutex); |
35 | static LIST_HEAD(hybrid_tuner_instance_list); | ||
36 | 36 | ||
37 | /*---------------------------------------------------------------------*/ | 37 | /*---------------------------------------------------------------------*/ |
38 | 38 | ||
@@ -986,16 +986,9 @@ static int tda18271_release(struct dvb_frontend *fe) | |||
986 | 986 | ||
987 | mutex_lock(&tda18271_list_mutex); | 987 | mutex_lock(&tda18271_list_mutex); |
988 | 988 | ||
989 | priv->count--; | 989 | if (priv) |
990 | hybrid_tuner_release_state(priv); | ||
990 | 991 | ||
991 | if (!priv->count) { | ||
992 | tda_dbg("destroying instance @ %d-%04x\n", | ||
993 | i2c_adapter_id(priv->i2c_adap), | ||
994 | priv->i2c_addr); | ||
995 | list_del(&priv->tda18271_list); | ||
996 | |||
997 | kfree(priv); | ||
998 | } | ||
999 | mutex_unlock(&tda18271_list_mutex); | 992 | mutex_unlock(&tda18271_list_mutex); |
1000 | 993 | ||
1001 | fe->tuner_priv = NULL; | 994 | fe->tuner_priv = NULL; |
@@ -1109,7 +1102,8 @@ static int tda18271_get_id(struct dvb_frontend *fe) | |||
1109 | } | 1102 | } |
1110 | 1103 | ||
1111 | tda_info("%s detected @ %d-%04x%s\n", name, | 1104 | tda_info("%s detected @ %d-%04x%s\n", name, |
1112 | i2c_adapter_id(priv->i2c_adap), priv->i2c_addr, | 1105 | i2c_adapter_id(priv->i2c_props.adap), |
1106 | priv->i2c_props.addr, | ||
1113 | (0 == ret) ? "" : ", device not supported."); | 1107 | (0 == ret) ? "" : ", device not supported."); |
1114 | 1108 | ||
1115 | return ret; | 1109 | return ret; |
@@ -1136,46 +1130,25 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, | |||
1136 | struct tda18271_config *cfg) | 1130 | struct tda18271_config *cfg) |
1137 | { | 1131 | { |
1138 | struct tda18271_priv *priv = NULL; | 1132 | struct tda18271_priv *priv = NULL; |
1139 | int state_found = 0; | 1133 | int instance; |
1140 | 1134 | ||
1141 | mutex_lock(&tda18271_list_mutex); | 1135 | mutex_lock(&tda18271_list_mutex); |
1142 | 1136 | ||
1143 | list_for_each_entry(priv, &tda18271_list, tda18271_list) { | 1137 | instance = hybrid_tuner_request_state(struct tda18271_priv, priv, |
1144 | if ((i2c_adapter_id(priv->i2c_adap) == i2c_adapter_id(i2c)) && | 1138 | hybrid_tuner_instance_list, |
1145 | (priv->i2c_addr == addr)) { | 1139 | i2c, addr, "tda18271"); |
1146 | tda_dbg("attaching existing tuner @ %d-%04x\n", | 1140 | switch (instance) { |
1147 | i2c_adapter_id(priv->i2c_adap), | 1141 | case 0: |
1148 | priv->i2c_addr); | 1142 | goto fail; |
1149 | priv->count++; | 1143 | break; |
1150 | fe->tuner_priv = priv; | 1144 | case 1: |
1151 | state_found = 1; | 1145 | /* new tuner instance */ |
1152 | /* allow dvb driver to override i2c gate setting */ | ||
1153 | if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG)) | ||
1154 | priv->gate = cfg->gate; | ||
1155 | break; | ||
1156 | } | ||
1157 | } | ||
1158 | if (state_found == 0) { | ||
1159 | tda_dbg("creating new tuner instance @ %d-%04x\n", | ||
1160 | i2c_adapter_id(i2c), addr); | ||
1161 | |||
1162 | priv = kzalloc(sizeof(struct tda18271_priv), GFP_KERNEL); | ||
1163 | if (priv == NULL) { | ||
1164 | mutex_unlock(&tda18271_list_mutex); | ||
1165 | return NULL; | ||
1166 | } | ||
1167 | |||
1168 | priv->i2c_addr = addr; | ||
1169 | priv->i2c_adap = i2c; | ||
1170 | priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; | 1146 | priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; |
1171 | priv->cal_initialized = false; | 1147 | priv->cal_initialized = false; |
1172 | mutex_init(&priv->lock); | 1148 | mutex_init(&priv->lock); |
1173 | priv->count++; | ||
1174 | 1149 | ||
1175 | fe->tuner_priv = priv; | 1150 | fe->tuner_priv = priv; |
1176 | 1151 | ||
1177 | list_add_tail(&priv->tda18271_list, &tda18271_list); | ||
1178 | |||
1179 | if (tda18271_get_id(fe) < 0) | 1152 | if (tda18271_get_id(fe) < 0) |
1180 | goto fail; | 1153 | goto fail; |
1181 | 1154 | ||
@@ -1189,6 +1162,15 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, | |||
1189 | tda18271_rf_cal_init(fe); | 1162 | tda18271_rf_cal_init(fe); |
1190 | 1163 | ||
1191 | mutex_unlock(&priv->lock); | 1164 | mutex_unlock(&priv->lock); |
1165 | break; | ||
1166 | default: | ||
1167 | /* existing tuner instance */ | ||
1168 | fe->tuner_priv = priv; | ||
1169 | |||
1170 | /* allow dvb driver to override i2c gate setting */ | ||
1171 | if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG)) | ||
1172 | priv->gate = cfg->gate; | ||
1173 | break; | ||
1192 | } | 1174 | } |
1193 | 1175 | ||
1194 | /* override default std map with values in config struct */ | 1176 | /* override default std map with values in config struct */ |
diff --git a/drivers/media/dvb/frontends/tda18271-priv.h b/drivers/media/dvb/frontends/tda18271-priv.h index 7b939a5325f..840b1803d17 100644 --- a/drivers/media/dvb/frontends/tda18271-priv.h +++ b/drivers/media/dvb/frontends/tda18271-priv.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include "tuner-i2c.h" | ||
27 | #include "tda18271.h" | 28 | #include "tda18271.h" |
28 | 29 | ||
29 | #define R_ID 0x00 /* ID byte */ | 30 | #define R_ID 0x00 /* ID byte */ |
@@ -98,17 +99,15 @@ enum tda18271_ver { | |||
98 | }; | 99 | }; |
99 | 100 | ||
100 | struct tda18271_priv { | 101 | struct tda18271_priv { |
101 | u8 i2c_addr; | ||
102 | struct i2c_adapter *i2c_adap; | ||
103 | unsigned char tda18271_regs[TDA18271_NUM_REGS]; | 102 | unsigned char tda18271_regs[TDA18271_NUM_REGS]; |
104 | 103 | ||
105 | struct list_head tda18271_list; | 104 | struct list_head hybrid_tuner_instance_list; |
105 | struct tuner_i2c_props i2c_props; | ||
106 | 106 | ||
107 | enum tda18271_mode mode; | 107 | enum tda18271_mode mode; |
108 | enum tda18271_i2c_gate gate; | 108 | enum tda18271_i2c_gate gate; |
109 | enum tda18271_ver id; | 109 | enum tda18271_ver id; |
110 | 110 | ||
111 | unsigned int count; | ||
112 | unsigned int tm_rfcal; | 111 | unsigned int tm_rfcal; |
113 | unsigned int cal_initialized:1; | 112 | unsigned int cal_initialized:1; |
114 | 113 | ||