si2157.c (aeb8f932080d62cdc305a7ccca9d60de34908b30) si2157.c (073f38494ab9bad6edf589c74a1f09c358c5068c)
1/*
1/*
2 * Silicon Labs Si2147/2157/2158 silicon tuner driver
2 * Silicon Labs Si2146/2147/2157/2158 silicon tuner driver
3 *
4 * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *

--- 77 unchanged lines hidden (view full) ---

88 unsigned int chip_id;
89
90 dev_dbg(&s->client->dev, "\n");
91
92 if (s->fw_loaded)
93 goto warm;
94
95 /* power up */
3 *
4 * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *

--- 77 unchanged lines hidden (view full) ---

88 unsigned int chip_id;
89
90 dev_dbg(&s->client->dev, "\n");
91
92 if (s->fw_loaded)
93 goto warm;
94
95 /* power up */
96 memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
97 cmd.wlen = 15;
96 if (s->chiptype == SI2157_CHIPTYPE_SI2146) {
97 memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
98 cmd.wlen = 9;
99 } else {
100 memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
101 cmd.wlen = 15;
102 }
98 cmd.rlen = 1;
99 ret = si2157_cmd_execute(s, &cmd);
100 if (ret)
101 goto err;
102
103 /* query chip revision */
104 memcpy(cmd.args, "\x02", 1);
105 cmd.wlen = 1;
106 cmd.rlen = 13;
107 ret = si2157_cmd_execute(s, &cmd);
108 if (ret)
109 goto err;
110
111 chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
112 cmd.args[4] << 0;
113
114 #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
115 #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
116 #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
103 cmd.rlen = 1;
104 ret = si2157_cmd_execute(s, &cmd);
105 if (ret)
106 goto err;
107
108 /* query chip revision */
109 memcpy(cmd.args, "\x02", 1);
110 cmd.wlen = 1;
111 cmd.rlen = 13;
112 ret = si2157_cmd_execute(s, &cmd);
113 if (ret)
114 goto err;
115
116 chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
117 cmd.args[4] << 0;
118
119 #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
120 #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
121 #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
122 #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
117
118 switch (chip_id) {
119 case SI2158_A20:
120 fw_file = SI2158_A20_FIRMWARE;
121 break;
122 case SI2157_A30:
123 case SI2147_A30:
123
124 switch (chip_id) {
125 case SI2158_A20:
126 fw_file = SI2158_A20_FIRMWARE;
127 break;
128 case SI2157_A30:
129 case SI2147_A30:
130 case SI2146_A10:
124 goto skip_fw_download;
125 break;
126 default:
127 dev_err(&s->client->dev,
128 "unknown chip version Si21%d-%c%c%c\n",
129 cmd.args[2], cmd.args[1],
130 cmd.args[3], cmd.args[4]);
131 ret = -EINVAL;

--- 113 unchanged lines hidden (view full) ---

245 bandwidth = 0x08;
246 else
247 bandwidth = 0x0f;
248
249 switch (c->delivery_system) {
250 case SYS_ATSC:
251 delivery_system = 0x00;
252 break;
131 goto skip_fw_download;
132 break;
133 default:
134 dev_err(&s->client->dev,
135 "unknown chip version Si21%d-%c%c%c\n",
136 cmd.args[2], cmd.args[1],
137 cmd.args[3], cmd.args[4]);
138 ret = -EINVAL;

--- 113 unchanged lines hidden (view full) ---

252 bandwidth = 0x08;
253 else
254 bandwidth = 0x0f;
255
256 switch (c->delivery_system) {
257 case SYS_ATSC:
258 delivery_system = 0x00;
259 break;
260 case SYS_DVBC_ANNEX_B:
261 delivery_system = 0x10;
262 break;
253 case SYS_DVBT:
254 case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */
255 delivery_system = 0x20;
256 break;
257 case SYS_DVBC_ANNEX_A:
258 delivery_system = 0x30;
259 break;
260 default:

--- 6 unchanged lines hidden (view full) ---

267 if (s->inversion)
268 cmd.args[5] = 0x01;
269 cmd.wlen = 6;
270 cmd.rlen = 4;
271 ret = si2157_cmd_execute(s, &cmd);
272 if (ret)
273 goto err;
274
263 case SYS_DVBT:
264 case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */
265 delivery_system = 0x20;
266 break;
267 case SYS_DVBC_ANNEX_A:
268 delivery_system = 0x30;
269 break;
270 default:

--- 6 unchanged lines hidden (view full) ---

277 if (s->inversion)
278 cmd.args[5] = 0x01;
279 cmd.wlen = 6;
280 cmd.rlen = 4;
281 ret = si2157_cmd_execute(s, &cmd);
282 if (ret)
283 goto err;
284
275 memcpy(cmd.args, "\x14\x00\x02\x07\x01\x00", 6);
285 if (s->chiptype == SI2157_CHIPTYPE_SI2146)
286 memcpy(cmd.args, "\x14\x00\x02\x07\x00\x01", 6);
287 else
288 memcpy(cmd.args, "\x14\x00\x02\x07\x01\x00", 6);
276 cmd.wlen = 6;
277 cmd.rlen = 4;
278 ret = si2157_cmd_execute(s, &cmd);
279 if (ret)
280 goto err;
281
282 /* set frequency */
283 memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8);

--- 16 unchanged lines hidden (view full) ---

300static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
301{
302 *frequency = 5000000; /* default value of property 0x0706 */
303 return 0;
304}
305
306static const struct dvb_tuner_ops si2157_ops = {
307 .info = {
289 cmd.wlen = 6;
290 cmd.rlen = 4;
291 ret = si2157_cmd_execute(s, &cmd);
292 if (ret)
293 goto err;
294
295 /* set frequency */
296 memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8);

--- 16 unchanged lines hidden (view full) ---

313static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
314{
315 *frequency = 5000000; /* default value of property 0x0706 */
316 return 0;
317}
318
319static const struct dvb_tuner_ops si2157_ops = {
320 .info = {
308 .name = "Silicon Labs Si2157/Si2158",
321 .name = "Silicon Labs Si2146/2147/2157/2158",
309 .frequency_min = 110000000,
310 .frequency_max = 862000000,
311 },
312
313 .init = si2157_init,
314 .sleep = si2157_sleep,
315 .set_params = si2157_set_params,
316 .get_if_frequency = si2157_get_if_frequency,

--- 14 unchanged lines hidden (view full) ---

331 dev_err(&client->dev, "kzalloc() failed\n");
332 goto err;
333 }
334
335 s->client = client;
336 s->fe = cfg->fe;
337 s->inversion = cfg->inversion;
338 s->fw_loaded = false;
322 .frequency_min = 110000000,
323 .frequency_max = 862000000,
324 },
325
326 .init = si2157_init,
327 .sleep = si2157_sleep,
328 .set_params = si2157_set_params,
329 .get_if_frequency = si2157_get_if_frequency,

--- 14 unchanged lines hidden (view full) ---

344 dev_err(&client->dev, "kzalloc() failed\n");
345 goto err;
346 }
347
348 s->client = client;
349 s->fe = cfg->fe;
350 s->inversion = cfg->inversion;
351 s->fw_loaded = false;
352 s->chiptype = (u8)id->driver_data;
339 mutex_init(&s->i2c_mutex);
340
341 /* check if the tuner is there */
342 cmd.wlen = 0;
343 cmd.rlen = 1;
344 ret = si2157_cmd_execute(s, &cmd);
345 if (ret)
346 goto err;
347
348 fe->tuner_priv = s;
349 memcpy(&fe->ops.tuner_ops, &si2157_ops,
350 sizeof(struct dvb_tuner_ops));
351
352 i2c_set_clientdata(client, s);
353
354 dev_info(&s->client->dev,
353 mutex_init(&s->i2c_mutex);
354
355 /* check if the tuner is there */
356 cmd.wlen = 0;
357 cmd.rlen = 1;
358 ret = si2157_cmd_execute(s, &cmd);
359 if (ret)
360 goto err;
361
362 fe->tuner_priv = s;
363 memcpy(&fe->ops.tuner_ops, &si2157_ops,
364 sizeof(struct dvb_tuner_ops));
365
366 i2c_set_clientdata(client, s);
367
368 dev_info(&s->client->dev,
355 "Silicon Labs Si2157/Si2158 successfully attached\n");
369 "Silicon Labs %s successfully attached\n",
370 s->chiptype == SI2157_CHIPTYPE_SI2146 ?
371 "Si2146" : "Si2147/2157/2158");
372
356 return 0;
357err:
358 dev_dbg(&client->dev, "failed=%d\n", ret);
359 kfree(s);
360
361 return ret;
362}
363

--- 8 unchanged lines hidden (view full) ---

372 fe->tuner_priv = NULL;
373 kfree(s);
374
375 return 0;
376}
377
378static const struct i2c_device_id si2157_id[] = {
379 {"si2157", 0},
373 return 0;
374err:
375 dev_dbg(&client->dev, "failed=%d\n", ret);
376 kfree(s);
377
378 return ret;
379}
380

--- 8 unchanged lines hidden (view full) ---

389 fe->tuner_priv = NULL;
390 kfree(s);
391
392 return 0;
393}
394
395static const struct i2c_device_id si2157_id[] = {
396 {"si2157", 0},
397 {"si2146", 1},
380 {}
381};
382MODULE_DEVICE_TABLE(i2c, si2157_id);
383
384static struct i2c_driver si2157_driver = {
385 .driver = {
386 .owner = THIS_MODULE,
387 .name = "si2157",
388 },
389 .probe = si2157_probe,
390 .remove = si2157_remove,
391 .id_table = si2157_id,
392};
393
394module_i2c_driver(si2157_driver);
395
398 {}
399};
400MODULE_DEVICE_TABLE(i2c, si2157_id);
401
402static struct i2c_driver si2157_driver = {
403 .driver = {
404 .owner = THIS_MODULE,
405 .name = "si2157",
406 },
407 .probe = si2157_probe,
408 .remove = si2157_remove,
409 .id_table = si2157_id,
410};
411
412module_i2c_driver(si2157_driver);
413
396MODULE_DESCRIPTION("Silicon Labs Si2157/Si2158 silicon tuner driver");
414MODULE_DESCRIPTION("Silicon Labs Si2146/2147/2157/2158 silicon tuner driver");
397MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
398MODULE_LICENSE("GPL");
399MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
415MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
416MODULE_LICENSE("GPL");
417MODULE_FIRMWARE(SI2158_A20_FIRMWARE);