aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends
diff options
context:
space:
mode:
authorLuis Alves <ljalvs@gmail.com>2013-10-03 07:33:47 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-10-03 06:40:12 -0400
commitd10e8280c4c2513d3e7350c27d8e6f0fa03a5f71 (patch)
tree71416e674be5b5c3490fc77885effd07f8dc776c /drivers/media/dvb-frontends
parente6001482d49ffe1554f55c47a4ed903e86fe69a5 (diff)
[media] cx24117: use hybrid_tuner_request/release_state to share state between multiple instances
...and remove the frontend pointer param from cx24117_attach() Signed-off-by: Luis Alves <ljalvs@gmail.com> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/dvb-frontends')
-rw-r--r--drivers/media/dvb-frontends/cx24117.c72
-rw-r--r--drivers/media/dvb-frontends/cx24117.h4
2 files changed, 53 insertions, 23 deletions
diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c
index 3b6391352918..908730959e38 100644
--- a/drivers/media/dvb-frontends/cx24117.c
+++ b/drivers/media/dvb-frontends/cx24117.c
@@ -31,6 +31,7 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/firmware.h> 32#include <linux/firmware.h>
33 33
34#include "tuner-i2c.h"
34#include "dvb_frontend.h" 35#include "dvb_frontend.h"
35#include "cx24117.h" 36#include "cx24117.h"
36 37
@@ -145,6 +146,9 @@ enum cmds {
145 CMD_TUNERSLEEP = 0x36, 146 CMD_TUNERSLEEP = 0x36,
146}; 147};
147 148
149static LIST_HEAD(hybrid_tuner_instance_list);
150static DEFINE_MUTEX(cx24117_list_mutex);
151
148/* The Demod/Tuner can't easily provide these, we cache them */ 152/* The Demod/Tuner can't easily provide these, we cache them */
149struct cx24117_tuning { 153struct cx24117_tuning {
150 u32 frequency; 154 u32 frequency;
@@ -176,9 +180,11 @@ struct cx24117_priv {
176 u8 demod_address; 180 u8 demod_address;
177 struct i2c_adapter *i2c; 181 struct i2c_adapter *i2c;
178 u8 skip_fw_load; 182 u8 skip_fw_load;
179
180 struct mutex fe_lock; 183 struct mutex fe_lock;
181 atomic_t fe_nr; 184
185 /* Used for sharing this struct between demods */
186 struct tuner_i2c_props i2c_props;
187 struct list_head hybrid_tuner_instance_list;
182}; 188};
183 189
184/* one per each fe */ 190/* one per each fe */
@@ -536,7 +542,7 @@ static int cx24117_load_firmware(struct dvb_frontend *fe,
536 dev_dbg(&state->priv->i2c->dev, 542 dev_dbg(&state->priv->i2c->dev,
537 "%s() demod%d FW is %zu bytes (%02x %02x .. %02x %02x)\n", 543 "%s() demod%d FW is %zu bytes (%02x %02x .. %02x %02x)\n",
538 __func__, state->demod, fw->size, fw->data[0], fw->data[1], 544 __func__, state->demod, fw->size, fw->data[0], fw->data[1],
539 fw->data[fw->size-2], fw->data[fw->size-1]); 545 fw->data[fw->size - 2], fw->data[fw->size - 1]);
540 546
541 cx24117_writereg(state, 0xea, 0x00); 547 cx24117_writereg(state, 0xea, 0x00);
542 cx24117_writereg(state, 0xea, 0x01); 548 cx24117_writereg(state, 0xea, 0x01);
@@ -1116,37 +1122,64 @@ static int cx24117_diseqc_send_burst(struct dvb_frontend *fe,
1116 return 0; 1122 return 0;
1117} 1123}
1118 1124
1125static int cx24117_get_priv(struct cx24117_priv **priv,
1126 struct i2c_adapter *i2c, u8 client_address)
1127{
1128 int ret;
1129
1130 mutex_lock(&cx24117_list_mutex);
1131 ret = hybrid_tuner_request_state(struct cx24117_priv, (*priv),
1132 hybrid_tuner_instance_list, i2c, client_address, "cx24117");
1133 mutex_unlock(&cx24117_list_mutex);
1134
1135 return ret;
1136}
1137
1138static void cx24117_release_priv(struct cx24117_priv *priv)
1139{
1140 mutex_lock(&cx24117_list_mutex);
1141 if (priv != NULL)
1142 hybrid_tuner_release_state(priv);
1143 mutex_unlock(&cx24117_list_mutex);
1144}
1145
1119static void cx24117_release(struct dvb_frontend *fe) 1146static void cx24117_release(struct dvb_frontend *fe)
1120{ 1147{
1121 struct cx24117_state *state = fe->demodulator_priv; 1148 struct cx24117_state *state = fe->demodulator_priv;
1122 dev_dbg(&state->priv->i2c->dev, "%s demod%d\n", 1149 dev_dbg(&state->priv->i2c->dev, "%s demod%d\n",
1123 __func__, state->demod); 1150 __func__, state->demod);
1124 if (!atomic_dec_and_test(&state->priv->fe_nr)) 1151 cx24117_release_priv(state->priv);
1125 kfree(state->priv);
1126 kfree(state); 1152 kfree(state);
1127} 1153}
1128 1154
1129static struct dvb_frontend_ops cx24117_ops; 1155static struct dvb_frontend_ops cx24117_ops;
1130 1156
1131struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, 1157struct dvb_frontend *cx24117_attach(const struct cx24117_config *config,
1132 struct i2c_adapter *i2c, struct dvb_frontend *fe) 1158 struct i2c_adapter *i2c)
1133{ 1159{
1134 struct cx24117_state *state = NULL; 1160 struct cx24117_state *state = NULL;
1135 struct cx24117_priv *priv = NULL; 1161 struct cx24117_priv *priv = NULL;
1136 int demod = 0; 1162 int demod = 0;
1137 1163
1138 /* first frontend attaching */ 1164 /* get the common data struct for both demods */
1139 /* allocate shared priv struct */ 1165 demod = cx24117_get_priv(&priv, i2c, config->demod_address);
1140 if (fe == NULL) { 1166
1141 priv = kzalloc(sizeof(struct cx24117_priv), GFP_KERNEL); 1167 switch (demod) {
1142 if (priv == NULL) 1168 case 0:
1143 goto error1; 1169 dev_err(&state->priv->i2c->dev,
1170 "%s: Error attaching frontend %d\n",
1171 KBUILD_MODNAME, demod);
1172 goto error1;
1173 break;
1174 case 1:
1175 /* new priv instance */
1144 priv->i2c = i2c; 1176 priv->i2c = i2c;
1145 priv->demod_address = config->demod_address; 1177 priv->demod_address = config->demod_address;
1146 mutex_init(&priv->fe_lock); 1178 mutex_init(&priv->fe_lock);
1147 } else { 1179 break;
1148 demod = 1; 1180 default:
1149 priv = ((struct cx24117_state *) fe->demodulator_priv)->priv; 1181 /* existing priv instance */
1182 break;
1150 } 1183 }
1151 1184
1152 /* allocate memory for the internal state */ 1185 /* allocate memory for the internal state */
@@ -1154,7 +1187,7 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config,
1154 if (state == NULL) 1187 if (state == NULL)
1155 goto error2; 1188 goto error2;
1156 1189
1157 state->demod = demod; 1190 state->demod = demod - 1;
1158 state->priv = priv; 1191 state->priv = priv;
1159 1192
1160 /* test i2c bus for ack */ 1193 /* test i2c bus for ack */
@@ -1163,12 +1196,9 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config,
1163 goto error3; 1196 goto error3;
1164 } 1197 }
1165 1198
1166 /* nr of frontends using the module */
1167 atomic_inc(&priv->fe_nr);
1168
1169 dev_info(&state->priv->i2c->dev, 1199 dev_info(&state->priv->i2c->dev,
1170 "%s: Attaching frontend %d\n", 1200 "%s: Attaching frontend %d\n",
1171 KBUILD_MODNAME, demod); 1201 KBUILD_MODNAME, state->demod);
1172 1202
1173 /* create dvb_frontend */ 1203 /* create dvb_frontend */
1174 memcpy(&state->frontend.ops, &cx24117_ops, 1204 memcpy(&state->frontend.ops, &cx24117_ops,
@@ -1179,7 +1209,7 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config,
1179error3: 1209error3:
1180 kfree(state); 1210 kfree(state);
1181error2: 1211error2:
1182 kfree(priv); 1212 cx24117_release_priv(priv);
1183error1: 1213error1:
1184 return NULL; 1214 return NULL;
1185} 1215}
diff --git a/drivers/media/dvb-frontends/cx24117.h b/drivers/media/dvb-frontends/cx24117.h
index 5bc8f1119275..4e59e9574fa7 100644
--- a/drivers/media/dvb-frontends/cx24117.h
+++ b/drivers/media/dvb-frontends/cx24117.h
@@ -33,11 +33,11 @@ struct cx24117_config {
33#if IS_ENABLED(CONFIG_DVB_CX24117) 33#if IS_ENABLED(CONFIG_DVB_CX24117)
34extern struct dvb_frontend *cx24117_attach( 34extern struct dvb_frontend *cx24117_attach(
35 const struct cx24117_config *config, 35 const struct cx24117_config *config,
36 struct i2c_adapter *i2c, struct dvb_frontend *fe); 36 struct i2c_adapter *i2c);
37#else 37#else
38static inline struct dvb_frontend *cx24117_attach( 38static inline struct dvb_frontend *cx24117_attach(
39 const struct cx24117_config *config, 39 const struct cx24117_config *config,
40 struct i2c_adapter *i2c, struct dvb_frontend *fe) 40 struct i2c_adapter *i2c)
41{ 41{
42 dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__); 42 dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
43 return NULL; 43 return NULL;