1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * driver for Earthsoft PT1/PT2 |
4 | * |
5 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> |
6 | * |
7 | * based on pt1dvr - http://pt1dvr.sourceforge.jp/ |
8 | * by Tomoaki Ishikawa <tomy@users.sourceforge.jp> |
9 | */ |
10 | |
11 | #include <linux/kernel.h> |
12 | #include <linux/sched.h> |
13 | #include <linux/sched/signal.h> |
14 | #include <linux/hrtimer.h> |
15 | #include <linux/delay.h> |
16 | #include <linux/module.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/vmalloc.h> |
19 | #include <linux/pci.h> |
20 | #include <linux/kthread.h> |
21 | #include <linux/freezer.h> |
22 | #include <linux/ratelimit.h> |
23 | #include <linux/string.h> |
24 | #include <linux/i2c.h> |
25 | |
26 | #include <media/dvbdev.h> |
27 | #include <media/dvb_demux.h> |
28 | #include <media/dmxdev.h> |
29 | #include <media/dvb_net.h> |
30 | #include <media/dvb_frontend.h> |
31 | |
32 | #include "tc90522.h" |
33 | #include "qm1d1b0004.h" |
34 | #include "dvb-pll.h" |
35 | |
36 | #define DRIVER_NAME "earth-pt1" |
37 | |
38 | #define PT1_PAGE_SHIFT 12 |
39 | #define PT1_PAGE_SIZE (1 << PT1_PAGE_SHIFT) |
40 | #define PT1_NR_UPACKETS 1024 |
41 | #define PT1_NR_BUFS 511 |
42 | |
43 | struct pt1_buffer_page { |
44 | __le32 upackets[PT1_NR_UPACKETS]; |
45 | }; |
46 | |
47 | struct pt1_table_page { |
48 | __le32 next_pfn; |
49 | __le32 buf_pfns[PT1_NR_BUFS]; |
50 | }; |
51 | |
52 | struct pt1_buffer { |
53 | struct pt1_buffer_page *page; |
54 | dma_addr_t addr; |
55 | }; |
56 | |
57 | struct pt1_table { |
58 | struct pt1_table_page *page; |
59 | dma_addr_t addr; |
60 | struct pt1_buffer bufs[PT1_NR_BUFS]; |
61 | }; |
62 | |
63 | enum pt1_fe_clk { |
64 | PT1_FE_CLK_20MHZ, /* PT1 */ |
65 | PT1_FE_CLK_25MHZ, /* PT2 */ |
66 | }; |
67 | |
68 | #define PT1_NR_ADAPS 4 |
69 | |
70 | struct pt1_adapter; |
71 | |
72 | struct pt1 { |
73 | struct pci_dev *pdev; |
74 | void __iomem *regs; |
75 | struct i2c_adapter i2c_adap; |
76 | int i2c_running; |
77 | struct pt1_adapter *adaps[PT1_NR_ADAPS]; |
78 | struct pt1_table *tables; |
79 | struct task_struct *kthread; |
80 | int table_index; |
81 | int buf_index; |
82 | |
83 | struct mutex lock; |
84 | int power; |
85 | int reset; |
86 | |
87 | enum pt1_fe_clk fe_clk; |
88 | }; |
89 | |
90 | struct pt1_adapter { |
91 | struct pt1 *pt1; |
92 | int index; |
93 | |
94 | u8 *buf; |
95 | int upacket_count; |
96 | int packet_count; |
97 | int st_count; |
98 | |
99 | struct dvb_adapter adap; |
100 | struct dvb_demux demux; |
101 | int users; |
102 | struct dmxdev dmxdev; |
103 | struct dvb_frontend *fe; |
104 | struct i2c_client *demod_i2c_client; |
105 | struct i2c_client *tuner_i2c_client; |
106 | int (*orig_set_voltage)(struct dvb_frontend *fe, |
107 | enum fe_sec_voltage voltage); |
108 | int (*orig_sleep)(struct dvb_frontend *fe); |
109 | int (*orig_init)(struct dvb_frontend *fe); |
110 | |
111 | enum fe_sec_voltage voltage; |
112 | int sleep; |
113 | }; |
114 | |
115 | union pt1_tuner_config { |
116 | struct qm1d1b0004_config qm1d1b0004; |
117 | struct dvb_pll_config tda6651; |
118 | }; |
119 | |
120 | struct pt1_config { |
121 | struct i2c_board_info demod_info; |
122 | struct tc90522_config demod_cfg; |
123 | |
124 | struct i2c_board_info tuner_info; |
125 | union pt1_tuner_config tuner_cfg; |
126 | }; |
127 | |
128 | static const struct pt1_config pt1_configs[PT1_NR_ADAPS] = { |
129 | { |
130 | .demod_info = { |
131 | I2C_BOARD_INFO(TC90522_I2C_DEV_SAT, 0x1b), |
132 | }, |
133 | .tuner_info = { |
134 | I2C_BOARD_INFO("qm1d1b0004" , 0x60), |
135 | }, |
136 | }, |
137 | { |
138 | .demod_info = { |
139 | I2C_BOARD_INFO(TC90522_I2C_DEV_TER, 0x1a), |
140 | }, |
141 | .tuner_info = { |
142 | I2C_BOARD_INFO("tda665x_earthpt1" , 0x61), |
143 | }, |
144 | }, |
145 | { |
146 | .demod_info = { |
147 | I2C_BOARD_INFO(TC90522_I2C_DEV_SAT, 0x19), |
148 | }, |
149 | .tuner_info = { |
150 | I2C_BOARD_INFO("qm1d1b0004" , 0x60), |
151 | }, |
152 | }, |
153 | { |
154 | .demod_info = { |
155 | I2C_BOARD_INFO(TC90522_I2C_DEV_TER, 0x18), |
156 | }, |
157 | .tuner_info = { |
158 | I2C_BOARD_INFO("tda665x_earthpt1" , 0x61), |
159 | }, |
160 | }, |
161 | }; |
162 | |
163 | static const u8 va1j5jf8007s_20mhz_configs[][2] = { |
164 | {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, |
165 | {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, |
166 | {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, |
167 | {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0}, |
168 | }; |
169 | |
170 | static const u8 va1j5jf8007s_25mhz_configs[][2] = { |
171 | {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a}, |
172 | {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89}, |
173 | {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04}, |
174 | {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0}, |
175 | }; |
176 | |
177 | static const u8 va1j5jf8007t_20mhz_configs[][2] = { |
178 | {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, |
179 | {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00}, |
180 | {0x3b, 0x11}, {0x3c, 0x3f}, |
181 | {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03}, |
182 | {0xef, 0x01} |
183 | }; |
184 | |
185 | static const u8 va1j5jf8007t_25mhz_configs[][2] = { |
186 | {0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83}, |
187 | {0x3a, 0x04}, {0x3b, 0x11}, {0x3c, 0x3f}, {0x5c, 0x40}, {0x5f, 0x80}, |
188 | {0x75, 0x0a}, {0x76, 0x4c}, {0x77, 0x03}, {0xef, 0x01} |
189 | }; |
190 | |
191 | static int config_demod(struct i2c_client *cl, enum pt1_fe_clk clk) |
192 | { |
193 | int ret; |
194 | bool is_sat; |
195 | const u8 (*cfg_data)[2]; |
196 | int i, len; |
197 | |
198 | is_sat = !strncmp(cl->name, TC90522_I2C_DEV_SAT, |
199 | strlen(TC90522_I2C_DEV_SAT)); |
200 | if (is_sat) { |
201 | struct i2c_msg msg[2]; |
202 | u8 wbuf, rbuf; |
203 | |
204 | wbuf = 0x07; |
205 | msg[0].addr = cl->addr; |
206 | msg[0].flags = 0; |
207 | msg[0].len = 1; |
208 | msg[0].buf = &wbuf; |
209 | |
210 | msg[1].addr = cl->addr; |
211 | msg[1].flags = I2C_M_RD; |
212 | msg[1].len = 1; |
213 | msg[1].buf = &rbuf; |
214 | ret = i2c_transfer(adap: cl->adapter, msgs: msg, num: 2); |
215 | if (ret < 0) |
216 | return ret; |
217 | if (rbuf != 0x41) |
218 | return -EIO; |
219 | } |
220 | |
221 | /* frontend init */ |
222 | if (clk == PT1_FE_CLK_20MHZ) { |
223 | if (is_sat) { |
224 | cfg_data = va1j5jf8007s_20mhz_configs; |
225 | len = ARRAY_SIZE(va1j5jf8007s_20mhz_configs); |
226 | } else { |
227 | cfg_data = va1j5jf8007t_20mhz_configs; |
228 | len = ARRAY_SIZE(va1j5jf8007t_20mhz_configs); |
229 | } |
230 | } else { |
231 | if (is_sat) { |
232 | cfg_data = va1j5jf8007s_25mhz_configs; |
233 | len = ARRAY_SIZE(va1j5jf8007s_25mhz_configs); |
234 | } else { |
235 | cfg_data = va1j5jf8007t_25mhz_configs; |
236 | len = ARRAY_SIZE(va1j5jf8007t_25mhz_configs); |
237 | } |
238 | } |
239 | |
240 | for (i = 0; i < len; i++) { |
241 | ret = i2c_master_send(client: cl, buf: cfg_data[i], count: 2); |
242 | if (ret < 0) |
243 | return ret; |
244 | } |
245 | return 0; |
246 | } |
247 | |
248 | /* |
249 | * Init registers for (each pair of) terrestrial/satellite block in demod. |
250 | * Note that resetting terr. block also resets its peer sat. block as well. |
251 | * This function must be called before configuring any demod block |
252 | * (before pt1_wakeup(), fe->ops.init()). |
253 | */ |
254 | static int pt1_demod_block_init(struct pt1 *pt1) |
255 | { |
256 | struct i2c_client *cl; |
257 | u8 buf[2] = {0x01, 0x80}; |
258 | int ret; |
259 | int i; |
260 | |
261 | /* reset all terr. & sat. pairs first */ |
262 | for (i = 0; i < PT1_NR_ADAPS; i++) { |
263 | cl = pt1->adaps[i]->demod_i2c_client; |
264 | if (strncmp(cl->name, TC90522_I2C_DEV_TER, |
265 | strlen(TC90522_I2C_DEV_TER))) |
266 | continue; |
267 | |
268 | ret = i2c_master_send(client: cl, buf, count: 2); |
269 | if (ret < 0) |
270 | return ret; |
271 | usleep_range(min: 30000, max: 50000); |
272 | } |
273 | |
274 | for (i = 0; i < PT1_NR_ADAPS; i++) { |
275 | cl = pt1->adaps[i]->demod_i2c_client; |
276 | if (strncmp(cl->name, TC90522_I2C_DEV_SAT, |
277 | strlen(TC90522_I2C_DEV_SAT))) |
278 | continue; |
279 | |
280 | ret = i2c_master_send(client: cl, buf, count: 2); |
281 | if (ret < 0) |
282 | return ret; |
283 | usleep_range(min: 30000, max: 50000); |
284 | } |
285 | return 0; |
286 | } |
287 | |
288 | static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data) |
289 | { |
290 | writel(val: data, addr: pt1->regs + reg * 4); |
291 | } |
292 | |
293 | static u32 pt1_read_reg(struct pt1 *pt1, int reg) |
294 | { |
295 | return readl(addr: pt1->regs + reg * 4); |
296 | } |
297 | |
298 | static unsigned int pt1_nr_tables = 8; |
299 | module_param_named(nr_tables, pt1_nr_tables, uint, 0); |
300 | |
301 | static void pt1_increment_table_count(struct pt1 *pt1) |
302 | { |
303 | pt1_write_reg(pt1, reg: 0, data: 0x00000020); |
304 | } |
305 | |
306 | static void pt1_init_table_count(struct pt1 *pt1) |
307 | { |
308 | pt1_write_reg(pt1, reg: 0, data: 0x00000010); |
309 | } |
310 | |
311 | static void pt1_register_tables(struct pt1 *pt1, u32 first_pfn) |
312 | { |
313 | pt1_write_reg(pt1, reg: 5, data: first_pfn); |
314 | pt1_write_reg(pt1, reg: 0, data: 0x0c000040); |
315 | } |
316 | |
317 | static void pt1_unregister_tables(struct pt1 *pt1) |
318 | { |
319 | pt1_write_reg(pt1, reg: 0, data: 0x08080000); |
320 | } |
321 | |
322 | static int pt1_sync(struct pt1 *pt1) |
323 | { |
324 | int i; |
325 | for (i = 0; i < 57; i++) { |
326 | if (pt1_read_reg(pt1, reg: 0) & 0x20000000) |
327 | return 0; |
328 | pt1_write_reg(pt1, reg: 0, data: 0x00000008); |
329 | } |
330 | dev_err(&pt1->pdev->dev, "could not sync\n" ); |
331 | return -EIO; |
332 | } |
333 | |
334 | static u64 pt1_identify(struct pt1 *pt1) |
335 | { |
336 | int i; |
337 | u64 id = 0; |
338 | for (i = 0; i < 57; i++) { |
339 | id |= (u64)(pt1_read_reg(pt1, reg: 0) >> 30 & 1) << i; |
340 | pt1_write_reg(pt1, reg: 0, data: 0x00000008); |
341 | } |
342 | return id; |
343 | } |
344 | |
345 | static int pt1_unlock(struct pt1 *pt1) |
346 | { |
347 | int i; |
348 | pt1_write_reg(pt1, reg: 0, data: 0x00000008); |
349 | for (i = 0; i < 3; i++) { |
350 | if (pt1_read_reg(pt1, reg: 0) & 0x80000000) |
351 | return 0; |
352 | usleep_range(min: 1000, max: 2000); |
353 | } |
354 | dev_err(&pt1->pdev->dev, "could not unlock\n" ); |
355 | return -EIO; |
356 | } |
357 | |
358 | static int pt1_reset_pci(struct pt1 *pt1) |
359 | { |
360 | int i; |
361 | pt1_write_reg(pt1, reg: 0, data: 0x01010000); |
362 | pt1_write_reg(pt1, reg: 0, data: 0x01000000); |
363 | for (i = 0; i < 10; i++) { |
364 | if (pt1_read_reg(pt1, reg: 0) & 0x00000001) |
365 | return 0; |
366 | usleep_range(min: 1000, max: 2000); |
367 | } |
368 | dev_err(&pt1->pdev->dev, "could not reset PCI\n" ); |
369 | return -EIO; |
370 | } |
371 | |
372 | static int pt1_reset_ram(struct pt1 *pt1) |
373 | { |
374 | int i; |
375 | pt1_write_reg(pt1, reg: 0, data: 0x02020000); |
376 | pt1_write_reg(pt1, reg: 0, data: 0x02000000); |
377 | for (i = 0; i < 10; i++) { |
378 | if (pt1_read_reg(pt1, reg: 0) & 0x00000002) |
379 | return 0; |
380 | usleep_range(min: 1000, max: 2000); |
381 | } |
382 | dev_err(&pt1->pdev->dev, "could not reset RAM\n" ); |
383 | return -EIO; |
384 | } |
385 | |
386 | static int pt1_do_enable_ram(struct pt1 *pt1) |
387 | { |
388 | int i, j; |
389 | u32 status; |
390 | status = pt1_read_reg(pt1, reg: 0) & 0x00000004; |
391 | pt1_write_reg(pt1, reg: 0, data: 0x00000002); |
392 | for (i = 0; i < 10; i++) { |
393 | for (j = 0; j < 1024; j++) { |
394 | if ((pt1_read_reg(pt1, reg: 0) & 0x00000004) != status) |
395 | return 0; |
396 | } |
397 | usleep_range(min: 1000, max: 2000); |
398 | } |
399 | dev_err(&pt1->pdev->dev, "could not enable RAM\n" ); |
400 | return -EIO; |
401 | } |
402 | |
403 | static int pt1_enable_ram(struct pt1 *pt1) |
404 | { |
405 | int i, ret; |
406 | int phase; |
407 | usleep_range(min: 1000, max: 2000); |
408 | phase = pt1->pdev->device == 0x211a ? 128 : 166; |
409 | for (i = 0; i < phase; i++) { |
410 | ret = pt1_do_enable_ram(pt1); |
411 | if (ret < 0) |
412 | return ret; |
413 | } |
414 | return 0; |
415 | } |
416 | |
417 | static void pt1_disable_ram(struct pt1 *pt1) |
418 | { |
419 | pt1_write_reg(pt1, reg: 0, data: 0x0b0b0000); |
420 | } |
421 | |
422 | static void pt1_set_stream(struct pt1 *pt1, int index, int enabled) |
423 | { |
424 | pt1_write_reg(pt1, reg: 2, data: 1 << (index + 8) | enabled << index); |
425 | } |
426 | |
427 | static void pt1_init_streams(struct pt1 *pt1) |
428 | { |
429 | int i; |
430 | for (i = 0; i < PT1_NR_ADAPS; i++) |
431 | pt1_set_stream(pt1, index: i, enabled: 0); |
432 | } |
433 | |
434 | static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page) |
435 | { |
436 | u32 upacket; |
437 | int i; |
438 | int index; |
439 | struct pt1_adapter *adap; |
440 | int offset; |
441 | u8 *buf; |
442 | int sc; |
443 | |
444 | if (!page->upackets[PT1_NR_UPACKETS - 1]) |
445 | return 0; |
446 | |
447 | for (i = 0; i < PT1_NR_UPACKETS; i++) { |
448 | upacket = le32_to_cpu(page->upackets[i]); |
449 | index = (upacket >> 29) - 1; |
450 | if (index < 0 || index >= PT1_NR_ADAPS) |
451 | continue; |
452 | |
453 | adap = pt1->adaps[index]; |
454 | if (upacket >> 25 & 1) |
455 | adap->upacket_count = 0; |
456 | else if (!adap->upacket_count) |
457 | continue; |
458 | |
459 | if (upacket >> 24 & 1) |
460 | printk_ratelimited(KERN_INFO "earth-pt1: device buffer overflowing. table[%d] buf[%d]\n" , |
461 | pt1->table_index, pt1->buf_index); |
462 | sc = upacket >> 26 & 0x7; |
463 | if (adap->st_count != -1 && sc != ((adap->st_count + 1) & 0x7)) |
464 | printk_ratelimited(KERN_INFO "earth-pt1: data loss in streamID(adapter)[%d]\n" , |
465 | index); |
466 | adap->st_count = sc; |
467 | |
468 | buf = adap->buf; |
469 | offset = adap->packet_count * 188 + adap->upacket_count * 3; |
470 | buf[offset] = upacket >> 16; |
471 | buf[offset + 1] = upacket >> 8; |
472 | if (adap->upacket_count != 62) |
473 | buf[offset + 2] = upacket; |
474 | |
475 | if (++adap->upacket_count >= 63) { |
476 | adap->upacket_count = 0; |
477 | if (++adap->packet_count >= 21) { |
478 | dvb_dmx_swfilter_packets(demux: &adap->demux, buf, count: 21); |
479 | adap->packet_count = 0; |
480 | } |
481 | } |
482 | } |
483 | |
484 | page->upackets[PT1_NR_UPACKETS - 1] = 0; |
485 | return 1; |
486 | } |
487 | |
488 | static int pt1_thread(void *data) |
489 | { |
490 | struct pt1 *pt1; |
491 | struct pt1_buffer_page *page; |
492 | bool was_frozen; |
493 | |
494 | #define PT1_FETCH_DELAY 10 |
495 | #define PT1_FETCH_DELAY_DELTA 2 |
496 | |
497 | pt1 = data; |
498 | set_freezable(); |
499 | |
500 | while (!kthread_freezable_should_stop(was_frozen: &was_frozen)) { |
501 | if (was_frozen) { |
502 | int i; |
503 | |
504 | for (i = 0; i < PT1_NR_ADAPS; i++) |
505 | pt1_set_stream(pt1, index: i, enabled: !!pt1->adaps[i]->users); |
506 | } |
507 | |
508 | page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page; |
509 | if (!pt1_filter(pt1, page)) { |
510 | ktime_t delay; |
511 | |
512 | delay = ktime_set(secs: 0, PT1_FETCH_DELAY * NSEC_PER_MSEC); |
513 | set_current_state(TASK_INTERRUPTIBLE); |
514 | schedule_hrtimeout_range(expires: &delay, |
515 | PT1_FETCH_DELAY_DELTA * NSEC_PER_MSEC, |
516 | mode: HRTIMER_MODE_REL); |
517 | continue; |
518 | } |
519 | |
520 | if (++pt1->buf_index >= PT1_NR_BUFS) { |
521 | pt1_increment_table_count(pt1); |
522 | pt1->buf_index = 0; |
523 | if (++pt1->table_index >= pt1_nr_tables) |
524 | pt1->table_index = 0; |
525 | } |
526 | } |
527 | |
528 | return 0; |
529 | } |
530 | |
531 | static void pt1_free_page(struct pt1 *pt1, void *page, dma_addr_t addr) |
532 | { |
533 | dma_free_coherent(dev: &pt1->pdev->dev, PT1_PAGE_SIZE, cpu_addr: page, dma_handle: addr); |
534 | } |
535 | |
536 | static void *pt1_alloc_page(struct pt1 *pt1, dma_addr_t *addrp, u32 *pfnp) |
537 | { |
538 | void *page; |
539 | dma_addr_t addr; |
540 | |
541 | page = dma_alloc_coherent(dev: &pt1->pdev->dev, PT1_PAGE_SIZE, dma_handle: &addr, |
542 | GFP_KERNEL); |
543 | if (page == NULL) |
544 | return NULL; |
545 | |
546 | BUG_ON(addr & (PT1_PAGE_SIZE - 1)); |
547 | BUG_ON(addr >> PT1_PAGE_SHIFT >> 31 >> 1); |
548 | |
549 | *addrp = addr; |
550 | *pfnp = addr >> PT1_PAGE_SHIFT; |
551 | return page; |
552 | } |
553 | |
554 | static void pt1_cleanup_buffer(struct pt1 *pt1, struct pt1_buffer *buf) |
555 | { |
556 | pt1_free_page(pt1, page: buf->page, addr: buf->addr); |
557 | } |
558 | |
559 | static int |
560 | pt1_init_buffer(struct pt1 *pt1, struct pt1_buffer *buf, u32 *pfnp) |
561 | { |
562 | struct pt1_buffer_page *page; |
563 | dma_addr_t addr; |
564 | |
565 | page = pt1_alloc_page(pt1, addrp: &addr, pfnp); |
566 | if (page == NULL) |
567 | return -ENOMEM; |
568 | |
569 | page->upackets[PT1_NR_UPACKETS - 1] = 0; |
570 | |
571 | buf->page = page; |
572 | buf->addr = addr; |
573 | return 0; |
574 | } |
575 | |
576 | static void pt1_cleanup_table(struct pt1 *pt1, struct pt1_table *table) |
577 | { |
578 | int i; |
579 | |
580 | for (i = 0; i < PT1_NR_BUFS; i++) |
581 | pt1_cleanup_buffer(pt1, buf: &table->bufs[i]); |
582 | |
583 | pt1_free_page(pt1, page: table->page, addr: table->addr); |
584 | } |
585 | |
586 | static int |
587 | pt1_init_table(struct pt1 *pt1, struct pt1_table *table, u32 *pfnp) |
588 | { |
589 | struct pt1_table_page *page; |
590 | dma_addr_t addr; |
591 | int i, ret; |
592 | u32 buf_pfn; |
593 | |
594 | page = pt1_alloc_page(pt1, addrp: &addr, pfnp); |
595 | if (page == NULL) |
596 | return -ENOMEM; |
597 | |
598 | for (i = 0; i < PT1_NR_BUFS; i++) { |
599 | ret = pt1_init_buffer(pt1, buf: &table->bufs[i], pfnp: &buf_pfn); |
600 | if (ret < 0) |
601 | goto err; |
602 | |
603 | page->buf_pfns[i] = cpu_to_le32(buf_pfn); |
604 | } |
605 | |
606 | pt1_increment_table_count(pt1); |
607 | table->page = page; |
608 | table->addr = addr; |
609 | return 0; |
610 | |
611 | err: |
612 | while (i--) |
613 | pt1_cleanup_buffer(pt1, buf: &table->bufs[i]); |
614 | |
615 | pt1_free_page(pt1, page, addr); |
616 | return ret; |
617 | } |
618 | |
619 | static void pt1_cleanup_tables(struct pt1 *pt1) |
620 | { |
621 | struct pt1_table *tables; |
622 | int i; |
623 | |
624 | tables = pt1->tables; |
625 | pt1_unregister_tables(pt1); |
626 | |
627 | for (i = 0; i < pt1_nr_tables; i++) |
628 | pt1_cleanup_table(pt1, table: &tables[i]); |
629 | |
630 | vfree(addr: tables); |
631 | } |
632 | |
633 | static int pt1_init_tables(struct pt1 *pt1) |
634 | { |
635 | struct pt1_table *tables; |
636 | int i, ret; |
637 | u32 first_pfn, pfn; |
638 | |
639 | if (!pt1_nr_tables) |
640 | return 0; |
641 | |
642 | tables = vmalloc(array_size(pt1_nr_tables, sizeof(struct pt1_table))); |
643 | if (tables == NULL) |
644 | return -ENOMEM; |
645 | |
646 | pt1_init_table_count(pt1); |
647 | |
648 | i = 0; |
649 | ret = pt1_init_table(pt1, table: &tables[0], pfnp: &first_pfn); |
650 | if (ret) |
651 | goto err; |
652 | i++; |
653 | |
654 | while (i < pt1_nr_tables) { |
655 | ret = pt1_init_table(pt1, table: &tables[i], pfnp: &pfn); |
656 | if (ret) |
657 | goto err; |
658 | tables[i - 1].page->next_pfn = cpu_to_le32(pfn); |
659 | i++; |
660 | } |
661 | |
662 | tables[pt1_nr_tables - 1].page->next_pfn = cpu_to_le32(first_pfn); |
663 | |
664 | pt1_register_tables(pt1, first_pfn); |
665 | pt1->tables = tables; |
666 | return 0; |
667 | |
668 | err: |
669 | while (i--) |
670 | pt1_cleanup_table(pt1, table: &tables[i]); |
671 | |
672 | vfree(addr: tables); |
673 | return ret; |
674 | } |
675 | |
676 | static int pt1_start_polling(struct pt1 *pt1) |
677 | { |
678 | int ret = 0; |
679 | |
680 | mutex_lock(&pt1->lock); |
681 | if (!pt1->kthread) { |
682 | pt1->kthread = kthread_run(pt1_thread, pt1, "earth-pt1" ); |
683 | if (IS_ERR(ptr: pt1->kthread)) { |
684 | ret = PTR_ERR(ptr: pt1->kthread); |
685 | pt1->kthread = NULL; |
686 | } |
687 | } |
688 | mutex_unlock(lock: &pt1->lock); |
689 | return ret; |
690 | } |
691 | |
692 | static int pt1_start_feed(struct dvb_demux_feed *feed) |
693 | { |
694 | struct pt1_adapter *adap; |
695 | adap = container_of(feed->demux, struct pt1_adapter, demux); |
696 | if (!adap->users++) { |
697 | int ret; |
698 | |
699 | ret = pt1_start_polling(pt1: adap->pt1); |
700 | if (ret) |
701 | return ret; |
702 | pt1_set_stream(pt1: adap->pt1, index: adap->index, enabled: 1); |
703 | } |
704 | return 0; |
705 | } |
706 | |
707 | static void pt1_stop_polling(struct pt1 *pt1) |
708 | { |
709 | int i, count; |
710 | |
711 | mutex_lock(&pt1->lock); |
712 | for (i = 0, count = 0; i < PT1_NR_ADAPS; i++) |
713 | count += pt1->adaps[i]->users; |
714 | |
715 | if (count == 0 && pt1->kthread) { |
716 | kthread_stop(k: pt1->kthread); |
717 | pt1->kthread = NULL; |
718 | } |
719 | mutex_unlock(lock: &pt1->lock); |
720 | } |
721 | |
722 | static int pt1_stop_feed(struct dvb_demux_feed *feed) |
723 | { |
724 | struct pt1_adapter *adap; |
725 | adap = container_of(feed->demux, struct pt1_adapter, demux); |
726 | if (!--adap->users) { |
727 | pt1_set_stream(pt1: adap->pt1, index: adap->index, enabled: 0); |
728 | pt1_stop_polling(pt1: adap->pt1); |
729 | } |
730 | return 0; |
731 | } |
732 | |
733 | static void |
734 | pt1_update_power(struct pt1 *pt1) |
735 | { |
736 | int bits; |
737 | int i; |
738 | struct pt1_adapter *adap; |
739 | static const int sleep_bits[] = { |
740 | 1 << 4, |
741 | 1 << 6 | 1 << 7, |
742 | 1 << 5, |
743 | 1 << 6 | 1 << 8, |
744 | }; |
745 | |
746 | bits = pt1->power | !pt1->reset << 3; |
747 | mutex_lock(&pt1->lock); |
748 | for (i = 0; i < PT1_NR_ADAPS; i++) { |
749 | adap = pt1->adaps[i]; |
750 | switch (adap->voltage) { |
751 | case SEC_VOLTAGE_13: /* actually 11V */ |
752 | bits |= 1 << 2; |
753 | break; |
754 | case SEC_VOLTAGE_18: /* actually 15V */ |
755 | bits |= 1 << 1 | 1 << 2; |
756 | break; |
757 | default: |
758 | break; |
759 | } |
760 | |
761 | /* XXX: The bits should be changed depending on adap->sleep. */ |
762 | bits |= sleep_bits[i]; |
763 | } |
764 | pt1_write_reg(pt1, reg: 1, data: bits); |
765 | mutex_unlock(lock: &pt1->lock); |
766 | } |
767 | |
768 | static int pt1_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage) |
769 | { |
770 | struct pt1_adapter *adap; |
771 | |
772 | adap = container_of(fe->dvb, struct pt1_adapter, adap); |
773 | adap->voltage = voltage; |
774 | pt1_update_power(pt1: adap->pt1); |
775 | |
776 | if (adap->orig_set_voltage) |
777 | return adap->orig_set_voltage(fe, voltage); |
778 | else |
779 | return 0; |
780 | } |
781 | |
782 | static int pt1_sleep(struct dvb_frontend *fe) |
783 | { |
784 | struct pt1_adapter *adap; |
785 | int ret; |
786 | |
787 | adap = container_of(fe->dvb, struct pt1_adapter, adap); |
788 | |
789 | ret = 0; |
790 | if (adap->orig_sleep) |
791 | ret = adap->orig_sleep(fe); |
792 | |
793 | adap->sleep = 1; |
794 | pt1_update_power(pt1: adap->pt1); |
795 | return ret; |
796 | } |
797 | |
798 | static int pt1_wakeup(struct dvb_frontend *fe) |
799 | { |
800 | struct pt1_adapter *adap; |
801 | int ret; |
802 | |
803 | adap = container_of(fe->dvb, struct pt1_adapter, adap); |
804 | adap->sleep = 0; |
805 | pt1_update_power(pt1: adap->pt1); |
806 | usleep_range(min: 1000, max: 2000); |
807 | |
808 | ret = config_demod(cl: adap->demod_i2c_client, clk: adap->pt1->fe_clk); |
809 | if (ret == 0 && adap->orig_init) |
810 | ret = adap->orig_init(fe); |
811 | return ret; |
812 | } |
813 | |
814 | static void pt1_free_adapter(struct pt1_adapter *adap) |
815 | { |
816 | adap->demux.dmx.close(&adap->demux.dmx); |
817 | dvb_dmxdev_release(dmxdev: &adap->dmxdev); |
818 | dvb_dmx_release(demux: &adap->demux); |
819 | dvb_unregister_adapter(adap: &adap->adap); |
820 | free_page((unsigned long)adap->buf); |
821 | kfree(objp: adap); |
822 | } |
823 | |
824 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
825 | |
826 | static struct pt1_adapter * |
827 | pt1_alloc_adapter(struct pt1 *pt1) |
828 | { |
829 | struct pt1_adapter *adap; |
830 | void *buf; |
831 | struct dvb_adapter *dvb_adap; |
832 | struct dvb_demux *demux; |
833 | struct dmxdev *dmxdev; |
834 | int ret; |
835 | |
836 | adap = kzalloc(size: sizeof(struct pt1_adapter), GFP_KERNEL); |
837 | if (!adap) { |
838 | ret = -ENOMEM; |
839 | goto err; |
840 | } |
841 | |
842 | adap->pt1 = pt1; |
843 | |
844 | adap->voltage = SEC_VOLTAGE_OFF; |
845 | adap->sleep = 1; |
846 | |
847 | buf = (u8 *)__get_free_page(GFP_KERNEL); |
848 | if (!buf) { |
849 | ret = -ENOMEM; |
850 | goto err_kfree; |
851 | } |
852 | |
853 | adap->buf = buf; |
854 | adap->upacket_count = 0; |
855 | adap->packet_count = 0; |
856 | adap->st_count = -1; |
857 | |
858 | dvb_adap = &adap->adap; |
859 | dvb_adap->priv = adap; |
860 | ret = dvb_register_adapter(adap: dvb_adap, DRIVER_NAME, THIS_MODULE, |
861 | device: &pt1->pdev->dev, adapter_nums: adapter_nr); |
862 | if (ret < 0) |
863 | goto err_free_page; |
864 | |
865 | demux = &adap->demux; |
866 | demux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; |
867 | demux->priv = adap; |
868 | demux->feednum = 256; |
869 | demux->filternum = 256; |
870 | demux->start_feed = pt1_start_feed; |
871 | demux->stop_feed = pt1_stop_feed; |
872 | demux->write_to_decoder = NULL; |
873 | ret = dvb_dmx_init(demux); |
874 | if (ret < 0) |
875 | goto err_unregister_adapter; |
876 | |
877 | dmxdev = &adap->dmxdev; |
878 | dmxdev->filternum = 256; |
879 | dmxdev->demux = &demux->dmx; |
880 | dmxdev->capabilities = 0; |
881 | ret = dvb_dmxdev_init(dmxdev, adap: dvb_adap); |
882 | if (ret < 0) |
883 | goto err_dmx_release; |
884 | |
885 | return adap; |
886 | |
887 | err_dmx_release: |
888 | dvb_dmx_release(demux); |
889 | err_unregister_adapter: |
890 | dvb_unregister_adapter(adap: dvb_adap); |
891 | err_free_page: |
892 | free_page((unsigned long)buf); |
893 | err_kfree: |
894 | kfree(objp: adap); |
895 | err: |
896 | return ERR_PTR(error: ret); |
897 | } |
898 | |
899 | static void pt1_cleanup_adapters(struct pt1 *pt1) |
900 | { |
901 | int i; |
902 | for (i = 0; i < PT1_NR_ADAPS; i++) |
903 | pt1_free_adapter(adap: pt1->adaps[i]); |
904 | } |
905 | |
906 | static int pt1_init_adapters(struct pt1 *pt1) |
907 | { |
908 | int i; |
909 | struct pt1_adapter *adap; |
910 | int ret; |
911 | |
912 | for (i = 0; i < PT1_NR_ADAPS; i++) { |
913 | adap = pt1_alloc_adapter(pt1); |
914 | if (IS_ERR(ptr: adap)) { |
915 | ret = PTR_ERR(ptr: adap); |
916 | goto err; |
917 | } |
918 | |
919 | adap->index = i; |
920 | pt1->adaps[i] = adap; |
921 | } |
922 | return 0; |
923 | |
924 | err: |
925 | while (i--) |
926 | pt1_free_adapter(adap: pt1->adaps[i]); |
927 | |
928 | return ret; |
929 | } |
930 | |
931 | static void pt1_cleanup_frontend(struct pt1_adapter *adap) |
932 | { |
933 | dvb_unregister_frontend(fe: adap->fe); |
934 | dvb_module_release(client: adap->tuner_i2c_client); |
935 | dvb_module_release(client: adap->demod_i2c_client); |
936 | } |
937 | |
938 | static int pt1_init_frontend(struct pt1_adapter *adap, struct dvb_frontend *fe) |
939 | { |
940 | int ret; |
941 | |
942 | adap->orig_set_voltage = fe->ops.set_voltage; |
943 | adap->orig_sleep = fe->ops.sleep; |
944 | adap->orig_init = fe->ops.init; |
945 | fe->ops.set_voltage = pt1_set_voltage; |
946 | fe->ops.sleep = pt1_sleep; |
947 | fe->ops.init = pt1_wakeup; |
948 | |
949 | ret = dvb_register_frontend(dvb: &adap->adap, fe); |
950 | if (ret < 0) |
951 | return ret; |
952 | |
953 | adap->fe = fe; |
954 | return 0; |
955 | } |
956 | |
957 | static void pt1_cleanup_frontends(struct pt1 *pt1) |
958 | { |
959 | int i; |
960 | for (i = 0; i < PT1_NR_ADAPS; i++) |
961 | pt1_cleanup_frontend(adap: pt1->adaps[i]); |
962 | } |
963 | |
964 | static int pt1_init_frontends(struct pt1 *pt1) |
965 | { |
966 | int i; |
967 | int ret; |
968 | |
969 | for (i = 0; i < ARRAY_SIZE(pt1_configs); i++) { |
970 | const struct i2c_board_info *info; |
971 | struct tc90522_config dcfg; |
972 | struct i2c_client *cl; |
973 | |
974 | info = &pt1_configs[i].demod_info; |
975 | dcfg = pt1_configs[i].demod_cfg; |
976 | dcfg.tuner_i2c = NULL; |
977 | |
978 | ret = -ENODEV; |
979 | cl = dvb_module_probe(module_name: "tc90522" , name: info->type, adap: &pt1->i2c_adap, |
980 | addr: info->addr, platform_data: &dcfg); |
981 | if (!cl) |
982 | goto fe_unregister; |
983 | pt1->adaps[i]->demod_i2c_client = cl; |
984 | |
985 | if (!strncmp(cl->name, TC90522_I2C_DEV_SAT, |
986 | strlen(TC90522_I2C_DEV_SAT))) { |
987 | struct qm1d1b0004_config tcfg; |
988 | |
989 | info = &pt1_configs[i].tuner_info; |
990 | tcfg = pt1_configs[i].tuner_cfg.qm1d1b0004; |
991 | tcfg.fe = dcfg.fe; |
992 | cl = dvb_module_probe(module_name: "qm1d1b0004" , |
993 | name: info->type, adap: dcfg.tuner_i2c, |
994 | addr: info->addr, platform_data: &tcfg); |
995 | } else { |
996 | struct dvb_pll_config tcfg; |
997 | |
998 | info = &pt1_configs[i].tuner_info; |
999 | tcfg = pt1_configs[i].tuner_cfg.tda6651; |
1000 | tcfg.fe = dcfg.fe; |
1001 | cl = dvb_module_probe(module_name: "dvb_pll" , |
1002 | name: info->type, adap: dcfg.tuner_i2c, |
1003 | addr: info->addr, platform_data: &tcfg); |
1004 | } |
1005 | if (!cl) |
1006 | goto demod_release; |
1007 | pt1->adaps[i]->tuner_i2c_client = cl; |
1008 | |
1009 | ret = pt1_init_frontend(adap: pt1->adaps[i], fe: dcfg.fe); |
1010 | if (ret < 0) |
1011 | goto tuner_release; |
1012 | } |
1013 | |
1014 | ret = pt1_demod_block_init(pt1); |
1015 | if (ret < 0) |
1016 | goto fe_unregister; |
1017 | |
1018 | return 0; |
1019 | |
1020 | tuner_release: |
1021 | dvb_module_release(client: pt1->adaps[i]->tuner_i2c_client); |
1022 | demod_release: |
1023 | dvb_module_release(client: pt1->adaps[i]->demod_i2c_client); |
1024 | fe_unregister: |
1025 | dev_warn(&pt1->pdev->dev, "failed to init FE(%d).\n" , i); |
1026 | i--; |
1027 | for (; i >= 0; i--) { |
1028 | dvb_unregister_frontend(fe: pt1->adaps[i]->fe); |
1029 | dvb_module_release(client: pt1->adaps[i]->tuner_i2c_client); |
1030 | dvb_module_release(client: pt1->adaps[i]->demod_i2c_client); |
1031 | } |
1032 | return ret; |
1033 | } |
1034 | |
1035 | static void pt1_i2c_emit(struct pt1 *pt1, int addr, int busy, int read_enable, |
1036 | int clock, int data, int next_addr) |
1037 | { |
1038 | pt1_write_reg(pt1, reg: 4, data: addr << 18 | busy << 13 | read_enable << 12 | |
1039 | !clock << 11 | !data << 10 | next_addr); |
1040 | } |
1041 | |
1042 | static void pt1_i2c_write_bit(struct pt1 *pt1, int addr, int *addrp, int data) |
1043 | { |
1044 | pt1_i2c_emit(pt1, addr, busy: 1, read_enable: 0, clock: 0, data, next_addr: addr + 1); |
1045 | pt1_i2c_emit(pt1, addr: addr + 1, busy: 1, read_enable: 0, clock: 1, data, next_addr: addr + 2); |
1046 | pt1_i2c_emit(pt1, addr: addr + 2, busy: 1, read_enable: 0, clock: 0, data, next_addr: addr + 3); |
1047 | *addrp = addr + 3; |
1048 | } |
1049 | |
1050 | static void pt1_i2c_read_bit(struct pt1 *pt1, int addr, int *addrp) |
1051 | { |
1052 | pt1_i2c_emit(pt1, addr, busy: 1, read_enable: 0, clock: 0, data: 1, next_addr: addr + 1); |
1053 | pt1_i2c_emit(pt1, addr: addr + 1, busy: 1, read_enable: 0, clock: 1, data: 1, next_addr: addr + 2); |
1054 | pt1_i2c_emit(pt1, addr: addr + 2, busy: 1, read_enable: 1, clock: 1, data: 1, next_addr: addr + 3); |
1055 | pt1_i2c_emit(pt1, addr: addr + 3, busy: 1, read_enable: 0, clock: 0, data: 1, next_addr: addr + 4); |
1056 | *addrp = addr + 4; |
1057 | } |
1058 | |
1059 | static void pt1_i2c_write_byte(struct pt1 *pt1, int addr, int *addrp, int data) |
1060 | { |
1061 | int i; |
1062 | for (i = 0; i < 8; i++) |
1063 | pt1_i2c_write_bit(pt1, addr, addrp: &addr, data: data >> (7 - i) & 1); |
1064 | pt1_i2c_write_bit(pt1, addr, addrp: &addr, data: 1); |
1065 | *addrp = addr; |
1066 | } |
1067 | |
1068 | static void pt1_i2c_read_byte(struct pt1 *pt1, int addr, int *addrp, int last) |
1069 | { |
1070 | int i; |
1071 | for (i = 0; i < 8; i++) |
1072 | pt1_i2c_read_bit(pt1, addr, addrp: &addr); |
1073 | pt1_i2c_write_bit(pt1, addr, addrp: &addr, data: last); |
1074 | *addrp = addr; |
1075 | } |
1076 | |
1077 | static void pt1_i2c_prepare(struct pt1 *pt1, int addr, int *addrp) |
1078 | { |
1079 | pt1_i2c_emit(pt1, addr, busy: 1, read_enable: 0, clock: 1, data: 1, next_addr: addr + 1); |
1080 | pt1_i2c_emit(pt1, addr: addr + 1, busy: 1, read_enable: 0, clock: 1, data: 0, next_addr: addr + 2); |
1081 | pt1_i2c_emit(pt1, addr: addr + 2, busy: 1, read_enable: 0, clock: 0, data: 0, next_addr: addr + 3); |
1082 | *addrp = addr + 3; |
1083 | } |
1084 | |
1085 | static void |
1086 | pt1_i2c_write_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg) |
1087 | { |
1088 | int i; |
1089 | pt1_i2c_prepare(pt1, addr, addrp: &addr); |
1090 | pt1_i2c_write_byte(pt1, addr, addrp: &addr, data: msg->addr << 1); |
1091 | for (i = 0; i < msg->len; i++) |
1092 | pt1_i2c_write_byte(pt1, addr, addrp: &addr, data: msg->buf[i]); |
1093 | *addrp = addr; |
1094 | } |
1095 | |
1096 | static void |
1097 | pt1_i2c_read_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg) |
1098 | { |
1099 | int i; |
1100 | pt1_i2c_prepare(pt1, addr, addrp: &addr); |
1101 | pt1_i2c_write_byte(pt1, addr, addrp: &addr, data: msg->addr << 1 | 1); |
1102 | for (i = 0; i < msg->len; i++) |
1103 | pt1_i2c_read_byte(pt1, addr, addrp: &addr, last: i == msg->len - 1); |
1104 | *addrp = addr; |
1105 | } |
1106 | |
1107 | static int pt1_i2c_end(struct pt1 *pt1, int addr) |
1108 | { |
1109 | pt1_i2c_emit(pt1, addr, busy: 1, read_enable: 0, clock: 0, data: 0, next_addr: addr + 1); |
1110 | pt1_i2c_emit(pt1, addr: addr + 1, busy: 1, read_enable: 0, clock: 1, data: 0, next_addr: addr + 2); |
1111 | pt1_i2c_emit(pt1, addr: addr + 2, busy: 1, read_enable: 0, clock: 1, data: 1, next_addr: 0); |
1112 | |
1113 | pt1_write_reg(pt1, reg: 0, data: 0x00000004); |
1114 | do { |
1115 | if (signal_pending(current)) |
1116 | return -EINTR; |
1117 | usleep_range(min: 1000, max: 2000); |
1118 | } while (pt1_read_reg(pt1, reg: 0) & 0x00000080); |
1119 | return 0; |
1120 | } |
1121 | |
1122 | static void pt1_i2c_begin(struct pt1 *pt1, int *addrp) |
1123 | { |
1124 | int addr = 0; |
1125 | |
1126 | pt1_i2c_emit(pt1, addr, busy: 0, read_enable: 0, clock: 1, data: 1, next_addr: addr /* itself */); |
1127 | addr = addr + 1; |
1128 | |
1129 | if (!pt1->i2c_running) { |
1130 | pt1_i2c_emit(pt1, addr, busy: 1, read_enable: 0, clock: 1, data: 1, next_addr: addr + 1); |
1131 | pt1_i2c_emit(pt1, addr: addr + 1, busy: 1, read_enable: 0, clock: 1, data: 0, next_addr: addr + 2); |
1132 | addr = addr + 2; |
1133 | pt1->i2c_running = 1; |
1134 | } |
1135 | *addrp = addr; |
1136 | } |
1137 | |
1138 | static int pt1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) |
1139 | { |
1140 | struct pt1 *pt1; |
1141 | int i; |
1142 | struct i2c_msg *msg, *next_msg; |
1143 | int addr, ret; |
1144 | u16 len; |
1145 | u32 word; |
1146 | |
1147 | pt1 = i2c_get_adapdata(adap); |
1148 | |
1149 | for (i = 0; i < num; i++) { |
1150 | msg = &msgs[i]; |
1151 | if (msg->flags & I2C_M_RD) |
1152 | return -ENOTSUPP; |
1153 | |
1154 | if (i + 1 < num) |
1155 | next_msg = &msgs[i + 1]; |
1156 | else |
1157 | next_msg = NULL; |
1158 | |
1159 | if (next_msg && next_msg->flags & I2C_M_RD) { |
1160 | i++; |
1161 | |
1162 | len = next_msg->len; |
1163 | if (len > 4) |
1164 | return -ENOTSUPP; |
1165 | |
1166 | pt1_i2c_begin(pt1, addrp: &addr); |
1167 | pt1_i2c_write_msg(pt1, addr, addrp: &addr, msg); |
1168 | pt1_i2c_read_msg(pt1, addr, addrp: &addr, msg: next_msg); |
1169 | ret = pt1_i2c_end(pt1, addr); |
1170 | if (ret < 0) |
1171 | return ret; |
1172 | |
1173 | word = pt1_read_reg(pt1, reg: 2); |
1174 | while (len--) { |
1175 | next_msg->buf[len] = word; |
1176 | word >>= 8; |
1177 | } |
1178 | } else { |
1179 | pt1_i2c_begin(pt1, addrp: &addr); |
1180 | pt1_i2c_write_msg(pt1, addr, addrp: &addr, msg); |
1181 | ret = pt1_i2c_end(pt1, addr); |
1182 | if (ret < 0) |
1183 | return ret; |
1184 | } |
1185 | } |
1186 | |
1187 | return num; |
1188 | } |
1189 | |
1190 | static u32 pt1_i2c_func(struct i2c_adapter *adap) |
1191 | { |
1192 | return I2C_FUNC_I2C; |
1193 | } |
1194 | |
1195 | static const struct i2c_algorithm pt1_i2c_algo = { |
1196 | .master_xfer = pt1_i2c_xfer, |
1197 | .functionality = pt1_i2c_func, |
1198 | }; |
1199 | |
1200 | static void pt1_i2c_wait(struct pt1 *pt1) |
1201 | { |
1202 | int i; |
1203 | for (i = 0; i < 128; i++) |
1204 | pt1_i2c_emit(pt1, addr: 0, busy: 0, read_enable: 0, clock: 1, data: 1, next_addr: 0); |
1205 | } |
1206 | |
1207 | static void pt1_i2c_init(struct pt1 *pt1) |
1208 | { |
1209 | int i; |
1210 | for (i = 0; i < 1024; i++) |
1211 | pt1_i2c_emit(pt1, addr: i, busy: 0, read_enable: 0, clock: 1, data: 1, next_addr: 0); |
1212 | } |
1213 | |
1214 | #ifdef CONFIG_PM_SLEEP |
1215 | |
1216 | static int pt1_suspend(struct device *dev) |
1217 | { |
1218 | struct pt1 *pt1 = dev_get_drvdata(dev); |
1219 | |
1220 | pt1_init_streams(pt1); |
1221 | pt1_disable_ram(pt1); |
1222 | pt1->power = 0; |
1223 | pt1->reset = 1; |
1224 | pt1_update_power(pt1); |
1225 | return 0; |
1226 | } |
1227 | |
1228 | static int pt1_resume(struct device *dev) |
1229 | { |
1230 | struct pt1 *pt1 = dev_get_drvdata(dev); |
1231 | int ret; |
1232 | int i; |
1233 | |
1234 | pt1->power = 0; |
1235 | pt1->reset = 1; |
1236 | pt1_update_power(pt1); |
1237 | |
1238 | pt1_i2c_init(pt1); |
1239 | pt1_i2c_wait(pt1); |
1240 | |
1241 | ret = pt1_sync(pt1); |
1242 | if (ret < 0) |
1243 | goto resume_err; |
1244 | |
1245 | pt1_identify(pt1); |
1246 | |
1247 | ret = pt1_unlock(pt1); |
1248 | if (ret < 0) |
1249 | goto resume_err; |
1250 | |
1251 | ret = pt1_reset_pci(pt1); |
1252 | if (ret < 0) |
1253 | goto resume_err; |
1254 | |
1255 | ret = pt1_reset_ram(pt1); |
1256 | if (ret < 0) |
1257 | goto resume_err; |
1258 | |
1259 | ret = pt1_enable_ram(pt1); |
1260 | if (ret < 0) |
1261 | goto resume_err; |
1262 | |
1263 | pt1_init_streams(pt1); |
1264 | |
1265 | pt1->power = 1; |
1266 | pt1_update_power(pt1); |
1267 | msleep(msecs: 20); |
1268 | |
1269 | pt1->reset = 0; |
1270 | pt1_update_power(pt1); |
1271 | usleep_range(min: 1000, max: 2000); |
1272 | |
1273 | ret = pt1_demod_block_init(pt1); |
1274 | if (ret < 0) |
1275 | goto resume_err; |
1276 | |
1277 | for (i = 0; i < PT1_NR_ADAPS; i++) |
1278 | dvb_frontend_reinitialise(fe: pt1->adaps[i]->fe); |
1279 | |
1280 | pt1_init_table_count(pt1); |
1281 | for (i = 0; i < pt1_nr_tables; i++) { |
1282 | int j; |
1283 | |
1284 | for (j = 0; j < PT1_NR_BUFS; j++) |
1285 | pt1->tables[i].bufs[j].page->upackets[PT1_NR_UPACKETS-1] |
1286 | = 0; |
1287 | pt1_increment_table_count(pt1); |
1288 | } |
1289 | pt1_register_tables(pt1, first_pfn: pt1->tables[0].addr >> PT1_PAGE_SHIFT); |
1290 | |
1291 | pt1->table_index = 0; |
1292 | pt1->buf_index = 0; |
1293 | for (i = 0; i < PT1_NR_ADAPS; i++) { |
1294 | pt1->adaps[i]->upacket_count = 0; |
1295 | pt1->adaps[i]->packet_count = 0; |
1296 | pt1->adaps[i]->st_count = -1; |
1297 | } |
1298 | |
1299 | return 0; |
1300 | |
1301 | resume_err: |
1302 | dev_info(&pt1->pdev->dev, "failed to resume PT1/PT2." ); |
1303 | return 0; /* resume anyway */ |
1304 | } |
1305 | |
1306 | #endif /* CONFIG_PM_SLEEP */ |
1307 | |
1308 | static void pt1_remove(struct pci_dev *pdev) |
1309 | { |
1310 | struct pt1 *pt1; |
1311 | void __iomem *regs; |
1312 | |
1313 | pt1 = pci_get_drvdata(pdev); |
1314 | regs = pt1->regs; |
1315 | |
1316 | if (pt1->kthread) |
1317 | kthread_stop(k: pt1->kthread); |
1318 | pt1_cleanup_tables(pt1); |
1319 | pt1_cleanup_frontends(pt1); |
1320 | pt1_disable_ram(pt1); |
1321 | pt1->power = 0; |
1322 | pt1->reset = 1; |
1323 | pt1_update_power(pt1); |
1324 | pt1_cleanup_adapters(pt1); |
1325 | i2c_del_adapter(adap: &pt1->i2c_adap); |
1326 | kfree(objp: pt1); |
1327 | pci_iounmap(dev: pdev, regs); |
1328 | pci_release_regions(pdev); |
1329 | pci_disable_device(dev: pdev); |
1330 | } |
1331 | |
1332 | static int pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
1333 | { |
1334 | int ret; |
1335 | void __iomem *regs; |
1336 | struct pt1 *pt1; |
1337 | struct i2c_adapter *i2c_adap; |
1338 | |
1339 | ret = pci_enable_device(dev: pdev); |
1340 | if (ret < 0) |
1341 | goto err; |
1342 | |
1343 | ret = dma_set_mask(dev: &pdev->dev, DMA_BIT_MASK(32)); |
1344 | if (ret < 0) |
1345 | goto err_pci_disable_device; |
1346 | |
1347 | pci_set_master(dev: pdev); |
1348 | |
1349 | ret = pci_request_regions(pdev, DRIVER_NAME); |
1350 | if (ret < 0) |
1351 | goto err_pci_disable_device; |
1352 | |
1353 | regs = pci_iomap(dev: pdev, bar: 0, max: 0); |
1354 | if (!regs) { |
1355 | ret = -EIO; |
1356 | goto err_pci_release_regions; |
1357 | } |
1358 | |
1359 | pt1 = kzalloc(size: sizeof(struct pt1), GFP_KERNEL); |
1360 | if (!pt1) { |
1361 | ret = -ENOMEM; |
1362 | goto err_pci_iounmap; |
1363 | } |
1364 | |
1365 | mutex_init(&pt1->lock); |
1366 | pt1->pdev = pdev; |
1367 | pt1->regs = regs; |
1368 | pt1->fe_clk = (pdev->device == 0x211a) ? |
1369 | PT1_FE_CLK_20MHZ : PT1_FE_CLK_25MHZ; |
1370 | pci_set_drvdata(pdev, data: pt1); |
1371 | |
1372 | ret = pt1_init_adapters(pt1); |
1373 | if (ret < 0) |
1374 | goto err_kfree; |
1375 | |
1376 | mutex_init(&pt1->lock); |
1377 | |
1378 | pt1->power = 0; |
1379 | pt1->reset = 1; |
1380 | pt1_update_power(pt1); |
1381 | |
1382 | i2c_adap = &pt1->i2c_adap; |
1383 | i2c_adap->algo = &pt1_i2c_algo; |
1384 | i2c_adap->algo_data = NULL; |
1385 | i2c_adap->dev.parent = &pdev->dev; |
1386 | strscpy(i2c_adap->name, DRIVER_NAME, sizeof(i2c_adap->name)); |
1387 | i2c_set_adapdata(adap: i2c_adap, data: pt1); |
1388 | ret = i2c_add_adapter(adap: i2c_adap); |
1389 | if (ret < 0) |
1390 | goto err_pt1_cleanup_adapters; |
1391 | |
1392 | pt1_i2c_init(pt1); |
1393 | pt1_i2c_wait(pt1); |
1394 | |
1395 | ret = pt1_sync(pt1); |
1396 | if (ret < 0) |
1397 | goto err_i2c_del_adapter; |
1398 | |
1399 | pt1_identify(pt1); |
1400 | |
1401 | ret = pt1_unlock(pt1); |
1402 | if (ret < 0) |
1403 | goto err_i2c_del_adapter; |
1404 | |
1405 | ret = pt1_reset_pci(pt1); |
1406 | if (ret < 0) |
1407 | goto err_i2c_del_adapter; |
1408 | |
1409 | ret = pt1_reset_ram(pt1); |
1410 | if (ret < 0) |
1411 | goto err_i2c_del_adapter; |
1412 | |
1413 | ret = pt1_enable_ram(pt1); |
1414 | if (ret < 0) |
1415 | goto err_i2c_del_adapter; |
1416 | |
1417 | pt1_init_streams(pt1); |
1418 | |
1419 | pt1->power = 1; |
1420 | pt1_update_power(pt1); |
1421 | msleep(msecs: 20); |
1422 | |
1423 | pt1->reset = 0; |
1424 | pt1_update_power(pt1); |
1425 | usleep_range(min: 1000, max: 2000); |
1426 | |
1427 | ret = pt1_init_frontends(pt1); |
1428 | if (ret < 0) |
1429 | goto err_pt1_disable_ram; |
1430 | |
1431 | ret = pt1_init_tables(pt1); |
1432 | if (ret < 0) |
1433 | goto err_pt1_cleanup_frontends; |
1434 | |
1435 | return 0; |
1436 | |
1437 | err_pt1_cleanup_frontends: |
1438 | pt1_cleanup_frontends(pt1); |
1439 | err_pt1_disable_ram: |
1440 | pt1_disable_ram(pt1); |
1441 | pt1->power = 0; |
1442 | pt1->reset = 1; |
1443 | pt1_update_power(pt1); |
1444 | err_i2c_del_adapter: |
1445 | i2c_del_adapter(adap: i2c_adap); |
1446 | err_pt1_cleanup_adapters: |
1447 | pt1_cleanup_adapters(pt1); |
1448 | err_kfree: |
1449 | kfree(objp: pt1); |
1450 | err_pci_iounmap: |
1451 | pci_iounmap(dev: pdev, regs); |
1452 | err_pci_release_regions: |
1453 | pci_release_regions(pdev); |
1454 | err_pci_disable_device: |
1455 | pci_disable_device(dev: pdev); |
1456 | err: |
1457 | return ret; |
1458 | |
1459 | } |
1460 | |
1461 | static const struct pci_device_id pt1_id_table[] = { |
1462 | { PCI_DEVICE(0x10ee, 0x211a) }, |
1463 | { PCI_DEVICE(0x10ee, 0x222a) }, |
1464 | { }, |
1465 | }; |
1466 | MODULE_DEVICE_TABLE(pci, pt1_id_table); |
1467 | |
1468 | static SIMPLE_DEV_PM_OPS(pt1_pm_ops, pt1_suspend, pt1_resume); |
1469 | |
1470 | static struct pci_driver pt1_driver = { |
1471 | .name = DRIVER_NAME, |
1472 | .probe = pt1_probe, |
1473 | .remove = pt1_remove, |
1474 | .id_table = pt1_id_table, |
1475 | .driver.pm = &pt1_pm_ops, |
1476 | }; |
1477 | |
1478 | module_pci_driver(pt1_driver); |
1479 | |
1480 | MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>" ); |
1481 | MODULE_DESCRIPTION("Earthsoft PT1/PT2 Driver" ); |
1482 | MODULE_LICENSE("GPL" ); |
1483 | |