aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/tuners/tua9001.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/tuners/tua9001.c')
-rw-r--r--drivers/media/tuners/tua9001.c331
1 files changed, 160 insertions, 171 deletions
diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c
index 83a6240f64d3..d4f6ca0c4d92 100644
--- a/drivers/media/tuners/tua9001.c
+++ b/drivers/media/tuners/tua9001.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Infineon TUA 9001 silicon tuner driver 2 * Infineon TUA9001 silicon tuner driver
3 * 3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi> 4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * 5 *
@@ -12,138 +12,87 @@
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */ 15 */
20 16
21#include "tua9001.h"
22#include "tua9001_priv.h" 17#include "tua9001_priv.h"
23 18
24/* write register */
25static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val)
26{
27 int ret;
28 u8 buf[3] = { reg, (val >> 8) & 0xff, (val >> 0) & 0xff };
29 struct i2c_msg msg[1] = {
30 {
31 .addr = priv->cfg->i2c_addr,
32 .flags = 0,
33 .len = sizeof(buf),
34 .buf = buf,
35 }
36 };
37
38 ret = i2c_transfer(priv->i2c, msg, 1);
39 if (ret == 1) {
40 ret = 0;
41 } else {
42 dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x\n",
43 KBUILD_MODNAME, ret, reg);
44 ret = -EREMOTEIO;
45 }
46
47 return ret;
48}
49
50static int tua9001_release(struct dvb_frontend *fe)
51{
52 struct tua9001_priv *priv = fe->tuner_priv;
53 int ret = 0;
54
55 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
56
57 if (fe->callback)
58 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
59 TUA9001_CMD_CEN, 0);
60
61 kfree(fe->tuner_priv);
62 fe->tuner_priv = NULL;
63
64 return ret;
65}
66
67static int tua9001_init(struct dvb_frontend *fe) 19static int tua9001_init(struct dvb_frontend *fe)
68{ 20{
69 struct tua9001_priv *priv = fe->tuner_priv; 21 struct tua9001_dev *dev = fe->tuner_priv;
70 int ret = 0; 22 struct i2c_client *client = dev->client;
71 u8 i; 23 int ret, i;
72 struct reg_val data[] = { 24 static const struct tua9001_reg_val data[] = {
73 { 0x1e, 0x6512 }, 25 {0x1e, 0x6512},
74 { 0x25, 0xb888 }, 26 {0x25, 0xb888},
75 { 0x39, 0x5460 }, 27 {0x39, 0x5460},
76 { 0x3b, 0x00c0 }, 28 {0x3b, 0x00c0},
77 { 0x3a, 0xf000 }, 29 {0x3a, 0xf000},
78 { 0x08, 0x0000 }, 30 {0x08, 0x0000},
79 { 0x32, 0x0030 }, 31 {0x32, 0x0030},
80 { 0x41, 0x703a }, 32 {0x41, 0x703a},
81 { 0x40, 0x1c78 }, 33 {0x40, 0x1c78},
82 { 0x2c, 0x1c00 }, 34 {0x2c, 0x1c00},
83 { 0x36, 0xc013 }, 35 {0x36, 0xc013},
84 { 0x37, 0x6f18 }, 36 {0x37, 0x6f18},
85 { 0x27, 0x0008 }, 37 {0x27, 0x0008},
86 { 0x2a, 0x0001 }, 38 {0x2a, 0x0001},
87 { 0x34, 0x0a40 }, 39 {0x34, 0x0a40},
88 }; 40 };
89 41
90 dev_dbg(&priv->i2c->dev, "%s:\n", __func__); 42 dev_dbg(&client->dev, "\n");
91 43
92 if (fe->callback) { 44 if (fe->callback) {
93 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, 45 ret = fe->callback(client->adapter,
94 TUA9001_CMD_RESETN, 0); 46 DVB_FRONTEND_COMPONENT_TUNER,
95 if (ret < 0) 47 TUA9001_CMD_RESETN, 0);
48 if (ret)
96 goto err; 49 goto err;
97 } 50 }
98 51
99 if (fe->ops.i2c_gate_ctrl)
100 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
101
102 for (i = 0; i < ARRAY_SIZE(data); i++) { 52 for (i = 0; i < ARRAY_SIZE(data); i++) {
103 ret = tua9001_wr_reg(priv, data[i].reg, data[i].val); 53 ret = regmap_write(dev->regmap, data[i].reg, data[i].val);
104 if (ret < 0) 54 if (ret)
105 goto err_i2c_gate_ctrl; 55 goto err;
106 } 56 }
107 57 return 0;
108err_i2c_gate_ctrl:
109 if (fe->ops.i2c_gate_ctrl)
110 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
111err: 58err:
112 if (ret < 0) 59 dev_dbg(&client->dev, "failed=%d\n", ret);
113 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
114
115 return ret; 60 return ret;
116} 61}
117 62
118static int tua9001_sleep(struct dvb_frontend *fe) 63static int tua9001_sleep(struct dvb_frontend *fe)
119{ 64{
120 struct tua9001_priv *priv = fe->tuner_priv; 65 struct tua9001_dev *dev = fe->tuner_priv;
121 int ret = 0; 66 struct i2c_client *client = dev->client;
122 67 int ret;
123 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
124
125 if (fe->callback)
126 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
127 TUA9001_CMD_RESETN, 1);
128 68
129 if (ret < 0) 69 dev_dbg(&client->dev, "\n");
130 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
131 70
71 if (fe->callback) {
72 ret = fe->callback(client->adapter,
73 DVB_FRONTEND_COMPONENT_TUNER,
74 TUA9001_CMD_RESETN, 1);
75 if (ret)
76 goto err;
77 }
78 return 0;
79err:
80 dev_dbg(&client->dev, "failed=%d\n", ret);
132 return ret; 81 return ret;
133} 82}
134 83
135static int tua9001_set_params(struct dvb_frontend *fe) 84static int tua9001_set_params(struct dvb_frontend *fe)
136{ 85{
137 struct tua9001_priv *priv = fe->tuner_priv; 86 struct tua9001_dev *dev = fe->tuner_priv;
87 struct i2c_client *client = dev->client;
138 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 88 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
139 int ret = 0, i; 89 int ret, i;
140 u16 val; 90 u16 val;
141 u32 frequency; 91 struct tua9001_reg_val data[2];
142 struct reg_val data[2];
143 92
144 dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \ 93 dev_dbg(&client->dev,
145 "bandwidth_hz=%d\n", __func__, 94 "delivery_system=%u frequency=%u bandwidth_hz=%u\n",
146 c->delivery_system, c->frequency, c->bandwidth_hz); 95 c->delivery_system, c->frequency, c->bandwidth_hz);
147 96
148 switch (c->delivery_system) { 97 switch (c->delivery_system) {
149 case SYS_DVBT: 98 case SYS_DVBT:
@@ -172,70 +121,54 @@ static int tua9001_set_params(struct dvb_frontend *fe)
172 121
173 data[0].reg = 0x04; 122 data[0].reg = 0x04;
174 data[0].val = val; 123 data[0].val = val;
175
176 frequency = (c->frequency - 150000000);
177 frequency /= 100;
178 frequency *= 48;
179 frequency /= 10000;
180
181 data[1].reg = 0x1f; 124 data[1].reg = 0x1f;
182 data[1].val = frequency; 125 data[1].val = div_u64((u64) (c->frequency - 150000000) * 48, 1000000);
183
184 if (fe->ops.i2c_gate_ctrl)
185 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
186 126
187 if (fe->callback) { 127 if (fe->callback) {
188 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, 128 ret = fe->callback(client->adapter,
189 TUA9001_CMD_RXEN, 0); 129 DVB_FRONTEND_COMPONENT_TUNER,
190 if (ret < 0) 130 TUA9001_CMD_RXEN, 0);
191 goto err_i2c_gate_ctrl; 131 if (ret)
132 goto err;
192 } 133 }
193 134
194 for (i = 0; i < ARRAY_SIZE(data); i++) { 135 for (i = 0; i < ARRAY_SIZE(data); i++) {
195 ret = tua9001_wr_reg(priv, data[i].reg, data[i].val); 136 ret = regmap_write(dev->regmap, data[i].reg, data[i].val);
196 if (ret < 0) 137 if (ret)
197 goto err_i2c_gate_ctrl; 138 goto err;
198 } 139 }
199 140
200 if (fe->callback) { 141 if (fe->callback) {
201 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, 142 ret = fe->callback(client->adapter,
202 TUA9001_CMD_RXEN, 1); 143 DVB_FRONTEND_COMPONENT_TUNER,
203 if (ret < 0) 144 TUA9001_CMD_RXEN, 1);
204 goto err_i2c_gate_ctrl; 145 if (ret)
146 goto err;
205 } 147 }
206 148 return 0;
207err_i2c_gate_ctrl:
208 if (fe->ops.i2c_gate_ctrl)
209 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
210err: 149err:
211 if (ret < 0) 150 dev_dbg(&client->dev, "failed=%d\n", ret);
212 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
213
214 return ret; 151 return ret;
215} 152}
216 153
217static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) 154static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
218{ 155{
219 struct tua9001_priv *priv = fe->tuner_priv; 156 struct tua9001_dev *dev = fe->tuner_priv;
157 struct i2c_client *client = dev->client;
220 158
221 dev_dbg(&priv->i2c->dev, "%s:\n", __func__); 159 dev_dbg(&client->dev, "\n");
222 160
223 *frequency = 0; /* Zero-IF */ 161 *frequency = 0; /* Zero-IF */
224
225 return 0; 162 return 0;
226} 163}
227 164
228static const struct dvb_tuner_ops tua9001_tuner_ops = { 165static const struct dvb_tuner_ops tua9001_tuner_ops = {
229 .info = { 166 .info = {
230 .name = "Infineon TUA 9001", 167 .name = "Infineon TUA9001",
231
232 .frequency_min = 170000000, 168 .frequency_min = 170000000,
233 .frequency_max = 862000000, 169 .frequency_max = 862000000,
234 .frequency_step = 0,
235 }, 170 },
236 171
237 .release = tua9001_release,
238
239 .init = tua9001_init, 172 .init = tua9001_init,
240 .sleep = tua9001_sleep, 173 .sleep = tua9001_sleep,
241 .set_params = tua9001_set_params, 174 .set_params = tua9001_set_params,
@@ -243,52 +176,108 @@ static const struct dvb_tuner_ops tua9001_tuner_ops = {
243 .get_if_frequency = tua9001_get_if_frequency, 176 .get_if_frequency = tua9001_get_if_frequency,
244}; 177};
245 178
246struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe, 179static int tua9001_probe(struct i2c_client *client,
247 struct i2c_adapter *i2c, struct tua9001_config *cfg) 180 const struct i2c_device_id *id)
248{ 181{
249 struct tua9001_priv *priv = NULL; 182 struct tua9001_dev *dev;
183 struct tua9001_platform_data *pdata = client->dev.platform_data;
184 struct dvb_frontend *fe = pdata->dvb_frontend;
250 int ret; 185 int ret;
186 static const struct regmap_config regmap_config = {
187 .reg_bits = 8,
188 .val_bits = 16,
189 };
251 190
252 priv = kzalloc(sizeof(struct tua9001_priv), GFP_KERNEL); 191 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
253 if (priv == NULL) 192 if (!dev) {
254 return NULL; 193 ret = -ENOMEM;
194 goto err;
195 }
255 196
256 priv->cfg = cfg; 197 dev->fe = pdata->dvb_frontend;
257 priv->i2c = i2c; 198 dev->client = client;
199 dev->regmap = devm_regmap_init_i2c(client, &regmap_config);
200 if (IS_ERR(dev->regmap)) {
201 ret = PTR_ERR(dev->regmap);
202 goto err_kfree;
203 }
258 204
259 if (fe->callback) { 205 if (fe->callback) {
260 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, 206 ret = fe->callback(client->adapter,
261 TUA9001_CMD_CEN, 1); 207 DVB_FRONTEND_COMPONENT_TUNER,
262 if (ret < 0) 208 TUA9001_CMD_CEN, 1);
263 goto err; 209 if (ret)
264 210 goto err_kfree;
265 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, 211
266 TUA9001_CMD_RXEN, 0); 212 ret = fe->callback(client->adapter,
267 if (ret < 0) 213 DVB_FRONTEND_COMPONENT_TUNER,
268 goto err; 214 TUA9001_CMD_RXEN, 0);
269 215 if (ret)
270 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, 216 goto err_kfree;
271 TUA9001_CMD_RESETN, 1); 217
272 if (ret < 0) 218 ret = fe->callback(client->adapter,
273 goto err; 219 DVB_FRONTEND_COMPONENT_TUNER,
220 TUA9001_CMD_RESETN, 1);
221 if (ret)
222 goto err_kfree;
274 } 223 }
275 224
276 dev_info(&priv->i2c->dev, 225 fe->tuner_priv = dev;
277 "%s: Infineon TUA 9001 successfully attached\n",
278 KBUILD_MODNAME);
279
280 memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops, 226 memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,
281 sizeof(struct dvb_tuner_ops)); 227 sizeof(struct dvb_tuner_ops));
228 i2c_set_clientdata(client, dev);
282 229
283 fe->tuner_priv = priv; 230 dev_info(&client->dev, "Infineon TUA9001 successfully attached\n");
284 return fe; 231 return 0;
232err_kfree:
233 kfree(dev);
285err: 234err:
286 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); 235 dev_dbg(&client->dev, "failed=%d\n", ret);
287 kfree(priv); 236 return ret;
288 return NULL; 237}
238
239static int tua9001_remove(struct i2c_client *client)
240{
241 struct tua9001_dev *dev = i2c_get_clientdata(client);
242 struct dvb_frontend *fe = dev->fe;
243 int ret;
244
245 dev_dbg(&client->dev, "\n");
246
247 if (fe->callback) {
248 ret = fe->callback(client->adapter,
249 DVB_FRONTEND_COMPONENT_TUNER,
250 TUA9001_CMD_CEN, 0);
251 if (ret)
252 goto err_kfree;
253 }
254 kfree(dev);
255 return 0;
256err_kfree:
257 kfree(dev);
258 dev_dbg(&client->dev, "failed=%d\n", ret);
259 return ret;
289} 260}
290EXPORT_SYMBOL(tua9001_attach);
291 261
292MODULE_DESCRIPTION("Infineon TUA 9001 silicon tuner driver"); 262static const struct i2c_device_id tua9001_id_table[] = {
263 {"tua9001", 0},
264 {}
265};
266MODULE_DEVICE_TABLE(i2c, tua9001_id_table);
267
268static struct i2c_driver tua9001_driver = {
269 .driver = {
270 .owner = THIS_MODULE,
271 .name = "tua9001",
272 .suppress_bind_attrs = true,
273 },
274 .probe = tua9001_probe,
275 .remove = tua9001_remove,
276 .id_table = tua9001_id_table,
277};
278
279module_i2c_driver(tua9001_driver);
280
281MODULE_DESCRIPTION("Infineon TUA9001 silicon tuner driver");
293MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 282MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
294MODULE_LICENSE("GPL"); 283MODULE_LICENSE("GPL");