summaryrefslogtreecommitdiff
path: root/drivers/stream_input/tv_frontend/aml_fe.c (plain)
blob: 6253def75c4fbc5aef2eaace8da5d9243e76fcce
1/*
2* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful, but WITHOUT
10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12* more details.
13*
14* You should have received a copy of the GNU General Public License along
15* with this program; if not, write to the Free Software Foundation, Inc.,
16* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*
18* Description:
19*/
20/*
21 * AMLOGIC DVB frontend driver.
22 */
23
24#include <linux/version.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/mutex.h>
28#include <linux/wait.h>
29#include <linux/string.h>
30#include <linux/interrupt.h>
31#include <linux/fs.h>
32#include <linux/cdev.h>
33#include <linux/device.h>
34#include <linux/spinlock.h>
35#include <linux/fcntl.h>
36#include <asm/irq.h>
37#include <linux/uaccess.h>
38#include <linux/poll.h>
39#include <linux/delay.h>
40#include <linux/platform_device.h>
41#include <linux/gpio/consumer.h>
42#include <linux/gpio.h>
43#include <linux/dma-contiguous.h>
44#include <linux/of_gpio.h>
45/*add for gpio api by hualing.chen*/
46#include <gpiolib.h>
47
48#include "aml_fe.h"
49
50#ifdef pr_dbg
51#undef pr_dbg
52#endif
53
54#define pr_dbg(fmt, args ...) \
55 pr_info("FE: " fmt, ## args)
56#define pr_error(fmt, args ...) pr_err("FE: " fmt, ## args)
57#define pr_inf(fmt, args ...) pr_info("FE: " fmt, ## args)
58
59static DEFINE_SPINLOCK(lock);
60static struct aml_fe_drv *tuner_drv_list;
61static struct aml_fe_drv *atv_demod_drv_list;
62static struct aml_fe_drv *dtv_demod_drv_list;
63static struct aml_fe_man fe_man;
64static long aml_fe_suspended;
65
66static int aml_fe_set_sys(struct dvb_frontend *dev,
67 enum fe_delivery_system sys);
68
69static struct aml_fe_drv **aml_get_fe_drv_list(enum aml_fe_dev_type_t type)
70{
71 switch (type) {
72 case AM_DEV_TUNER:
73 return &tuner_drv_list;
74 case AM_DEV_ATV_DEMOD:
75 return &atv_demod_drv_list;
76 case AM_DEV_DTV_DEMOD:
77 return &dtv_demod_drv_list;
78 default:
79 return NULL;
80 }
81}
82
83
84
85int amlogic_gpio_direction_output(unsigned int pin, int value,
86 const char *owner)
87{
88 gpio_direction_output(pin, value);
89 return 0;
90}
91EXPORT_SYMBOL(amlogic_gpio_direction_output);
92int amlogic_gpio_request(unsigned int pin, const char *label)
93{
94 return 0;
95}
96EXPORT_SYMBOL(amlogic_gpio_request);
97int aml_register_fe_drv(enum aml_fe_dev_type_t type, struct aml_fe_drv *drv)
98{
99 if (drv) {
100 struct aml_fe_drv **list = aml_get_fe_drv_list(type);
101 unsigned long flags;
102
103 spin_lock_irqsave(&lock, flags);
104
105 drv->next = *list;
106 *list = drv;
107
108 drv->ref = 0;
109
110 spin_unlock_irqrestore(&lock, flags);
111 }
112
113 return 0;
114}
115EXPORT_SYMBOL(aml_register_fe_drv);
116
117int aml_unregister_fe_drv(enum aml_fe_dev_type_t type, struct aml_fe_drv *drv)
118{
119 int ret = 0;
120
121 if (drv) {
122 struct aml_fe_drv *pdrv, *pprev;
123 struct aml_fe_drv **list = aml_get_fe_drv_list(type);
124 unsigned long flags;
125
126 spin_lock_irqsave(&lock, flags);
127
128 if (!drv->ref) {
129 for (pprev = NULL, pdrv = *list;
130 pdrv; pprev = pdrv, pdrv = pdrv->next) {
131 if (pdrv == drv) {
132 if (pprev)
133 pprev->next = pdrv->next;
134 else
135 *list = pdrv->next;
136 break;
137 }
138 }
139 } else {
140 pr_error("fe driver %d is inused\n", drv->id);
141 ret = -1;
142 }
143
144 spin_unlock_irqrestore(&lock, flags);
145 }
146
147 return ret;
148}
149EXPORT_SYMBOL(aml_unregister_fe_drv);
150
151static int aml_fe_support_sys(struct aml_fe *fe,
152 enum fe_delivery_system sys)
153{
154 if (fe->dtv_demod
155 && fe->dtv_demod->drv
156 && fe->dtv_demod->drv->support) {
157 if (!fe->dtv_demod->drv->support(fe->dtv_demod, sys))
158 return 0;
159 }
160
161 if (fe->atv_demod
162 && fe->atv_demod->drv
163 && fe->atv_demod->drv->support) {
164 if (!fe->atv_demod->drv->support(fe->atv_demod, sys))
165 return 0;
166 }
167
168 if (fe->tuner
169 && fe->tuner->drv
170 && fe->tuner->drv->support) {
171 if (!fe->tuner->drv->support(fe->tuner, sys))
172 return 0;
173 }
174
175 return 1;
176}
177/*
178 *#define DTV_START_BLIND_SCAN 71
179 *#define DTV_CANCEL_BLIND_SCAN 72
180 *#define DTV_BLIND_SCAN_MIN_FRE 73
181 *#define DTV_BLIND_SCAN_MAX_FRE 74
182 *#define DTV_BLIND_SCAN_MIN_SRATE 75
183 *#define DTV_BLIND_SCAN_MAX_SRATE 76
184 *#define DTV_BLIND_SCAN_FRE_RANGE 77
185 *#define DTV_BLIND_SCAN_FRE_STEP 78
186 *#define DTV_BLIND_SCAN_TIMEOUT 79
187 */
188static int aml_fe_blind_cmd(struct dvb_frontend *dev,
189 struct dtv_property *tvp)
190{
191 struct aml_fe *fe;
192 int ret = 0;
193
194 fe = dev->demodulator_priv;
195 pr_error("fe blind cmd into cmd:[%d]\n", tvp->cmd);
196 switch (tvp->cmd) {
197 case DTV_START_BLIND_SCAN:
198 if (fe->dtv_demod
199 && fe->dtv_demod->drv
200 && fe->dtv_demod->drv->start_blind_scan) {
201 ret = fe->dtv_demod->drv->start_blind_scan(
202 fe->dtv_demod);
203 } else {
204 pr_error("fe dtv_demod not surport blind start\n");
205 }
206 break;
207 case DTV_CANCEL_BLIND_SCAN:
208 if (fe->dtv_demod
209 && fe->dtv_demod->drv
210 && fe->dtv_demod->drv->stop_blind_scan) {
211 ret = fe->dtv_demod->drv->stop_blind_scan(
212 fe->dtv_demod);
213 } else {
214 pr_error("fe dtv_demod not surport blind stop\n");
215 }
216 break;
217 case DTV_BLIND_SCAN_MIN_FRE:
218 fe->blind_scan_para.minfrequency = tvp->u.data;
219 break;
220 case DTV_BLIND_SCAN_MAX_FRE:
221 fe->blind_scan_para.maxfrequency = tvp->u.data;
222 break;
223 case DTV_BLIND_SCAN_MIN_SRATE:
224 fe->blind_scan_para.minSymbolRate = tvp->u.data;
225 break;
226 case DTV_BLIND_SCAN_MAX_SRATE:
227 fe->blind_scan_para.maxSymbolRate = tvp->u.data;
228 break;
229 case DTV_BLIND_SCAN_FRE_RANGE:
230 fe->blind_scan_para.frequencyRange = tvp->u.data;
231 break;
232 case DTV_BLIND_SCAN_FRE_STEP:
233 fe->blind_scan_para.frequencyStep = tvp->u.data;
234 break;
235 case DTV_BLIND_SCAN_TIMEOUT:
236 fe->blind_scan_para.timeout = tvp->u.data;
237 break;
238 default:
239 ret = 0;
240 break;
241 }
242 return ret;
243}
244
245static int aml_fe_set_property(struct dvb_frontend *dev,
246 struct dtv_property *tvp)
247{
248 struct aml_fe *fe;
249 int r = 0;
250
251 fe = dev->demodulator_priv;
252
253 if (tvp->cmd == DTV_DELIVERY_SYSTEM) {
254 enum fe_delivery_system sys = tvp->u.data;
255
256 pr_error("fe aml_fe_set_property %d\n", sys);
257 r = aml_fe_set_sys(dev, sys);
258 if (r < 0)
259 return r;
260 }
261
262 if (tvp->cmd == DTV_DELIVERY_SUB_SYSTEM) {
263 int sub_sys = tvp->u.data;
264
265 pr_error("fe aml_fe_set_property sub_sys: %d\n", sub_sys);
266 fe->sub_sys = sub_sys;
267 r = 0;
268 }
269 pr_error("fe aml_fe_set_property -tvp->cmd[%d]\n", tvp->cmd);
270 switch (tvp->cmd) {
271 case DTV_START_BLIND_SCAN:
272 case DTV_CANCEL_BLIND_SCAN:
273 case DTV_BLIND_SCAN_MIN_FRE:
274 case DTV_BLIND_SCAN_MAX_FRE:
275 case DTV_BLIND_SCAN_MIN_SRATE:
276 case DTV_BLIND_SCAN_MAX_SRATE:
277 case DTV_BLIND_SCAN_FRE_RANGE:
278 case DTV_BLIND_SCAN_FRE_STEP:
279 case DTV_BLIND_SCAN_TIMEOUT:
280 r = aml_fe_blind_cmd(dev, tvp);
281 if (r < 0)
282 return r;
283 default:
284 break;
285 }
286
287 if (fe->set_property) {
288 pr_error("fe fe->set_property -0\n");
289 return fe->set_property(dev, tvp);
290 }
291 pr_error("fe aml_fe_set_property -2\n");
292 return r;
293}
294
295static int aml_fe_get_property(struct dvb_frontend *dev,
296 struct dtv_property *tvp)
297{
298 struct aml_fe *fe;
299 int r = 0;
300
301 fe = dev->demodulator_priv;
302
303 if (tvp->cmd == DTV_TS_INPUT)
304 tvp->u.data = fe->ts;
305 if (tvp->cmd == DTV_DELIVERY_SUB_SYSTEM) {
306 tvp->u.data = fe->sub_sys;
307 pr_error("fe aml_fe_get_property sub_sys: %d\n", fe->sub_sys);
308 r = 0;
309 }
310 if (fe->get_property)
311 return fe->get_property(dev, tvp);
312
313 return r;
314}
315
316static int aml_fe_set_sys(struct dvb_frontend *dev,
317 enum fe_delivery_system sys)
318{
319 struct aml_fe *fe = dev->demodulator_priv;
320 unsigned long flags;
321 int ret = -1;
322
323 if (fe->sys == sys) {
324 pr_dbg("[%s]:the mode is not change!!!!\n", __func__);
325 return 0;
326 }
327 /*set dvb-t or dvb-t2
328 * if dvb-t or t2 is set
329 * we only set sys value, not init sys
330 */
331 if (fe->sys != SYS_UNDEFINED) {
332 pr_dbg("release system %d\n", fe->sys);
333
334 if (fe->dtv_demod
335 && fe->dtv_demod->drv
336 && fe->dtv_demod->drv->release_sys)
337 fe->dtv_demod->drv->release_sys(fe->dtv_demod, fe->sys);
338 if (fe->atv_demod
339 && fe->atv_demod->drv
340 && fe->atv_demod->drv->release_sys)
341 fe->atv_demod->drv->release_sys(fe->atv_demod, fe->sys);
342 if (fe->tuner
343 && fe->tuner->drv
344 && fe->tuner->drv->release_sys)
345 fe->tuner->drv->release_sys(fe->tuner, fe->sys);
346
347 fe->set_property = NULL;
348 fe->get_property = NULL;
349
350 fe->sys = SYS_UNDEFINED;
351 }
352
353 if (sys == SYS_UNDEFINED)
354 return 0;
355
356 if (!aml_fe_support_sys(fe, sys)) {
357 int i;
358
359 spin_lock_irqsave(&lock, flags);
360 for (i = 0; i < FE_DEV_COUNT; i++) {
361 if (aml_fe_support_sys(&fe_man.fe[i], sys)
362 && (fe_man.fe[i].dev_id == fe->dev_id))
363 break;
364 }
365 spin_unlock_irqrestore(&lock, flags);
366
367 if (i >= FE_DEV_COUNT) {
368 pr_error("do not support delivery system %d\n", sys);
369 return -1;
370 }
371
372 fe = &fe_man.fe[i];
373 dev->demodulator_priv = fe;
374 }
375
376 spin_lock_irqsave(&fe->slock, flags);
377
378 memset(&fe->fe->ops.tuner_ops, 0, sizeof(fe->fe->ops.tuner_ops));
379 memset(&fe->fe->ops.analog_ops, 0, sizeof(fe->fe->ops.analog_ops));
380 memset(&fe->fe->ops.info, 0, sizeof(fe->fe->ops.info));
381 fe->fe->ops.release = NULL;
382 fe->fe->ops.release_sec = NULL;
383 fe->fe->ops.init = NULL;
384 fe->fe->ops.sleep = NULL;
385 fe->fe->ops.write = NULL;
386 fe->fe->ops.tune = NULL;
387 fe->fe->ops.get_frontend_algo = NULL;
388 fe->fe->ops.set_frontend = NULL;
389 fe->fe->ops.get_tune_settings = NULL;
390 fe->fe->ops.get_frontend = NULL;
391 fe->fe->ops.read_status = NULL;
392 fe->fe->ops.read_ber = NULL;
393 fe->fe->ops.read_signal_strength = NULL;
394 fe->fe->ops.read_snr = NULL;
395 fe->fe->ops.read_ucblocks = NULL;
396 fe->fe->ops.diseqc_reset_overload = NULL;
397 fe->fe->ops.diseqc_send_master_cmd = NULL;
398 fe->fe->ops.diseqc_recv_slave_reply = NULL;
399 fe->fe->ops.diseqc_send_burst = NULL;
400 fe->fe->ops.set_tone = NULL;
401 fe->fe->ops.set_voltage = NULL;
402 fe->fe->ops.enable_high_lnb_voltage = NULL;
403 fe->fe->ops.dishnetwork_send_legacy_command = NULL;
404 fe->fe->ops.i2c_gate_ctrl = NULL;
405 fe->fe->ops.ts_bus_ctrl = NULL;
406 fe->fe->ops.search = NULL;
407 fe->fe->ops.set_property = NULL;
408 fe->fe->ops.get_property = NULL;
409
410 if (fe->tuner
411 && fe->tuner->drv
412 && fe->tuner->drv->get_ops)
413 fe->tuner->drv->get_ops(fe->tuner, sys, &fe->fe->ops);
414
415 if (fe->atv_demod
416 && fe->atv_demod->drv
417 && fe->atv_demod->drv->get_ops)
418 fe->atv_demod->drv->get_ops(fe->atv_demod, sys, &fe->fe->ops);
419
420 if (fe->dtv_demod
421 && fe->dtv_demod->drv
422 && fe->dtv_demod->drv->get_ops)
423 fe->dtv_demod->drv->get_ops(fe->dtv_demod, sys, &fe->fe->ops);
424
425 spin_unlock_irqrestore(&fe->slock, flags);
426
427 pr_dbg("init system %d\n", sys);
428
429 if (fe->dtv_demod
430 && fe->dtv_demod->drv
431 && fe->dtv_demod->drv->init_sys)
432 ret = fe->dtv_demod->drv->init_sys(fe->dtv_demod, sys);
433 if (fe->atv_demod
434 && fe->atv_demod->drv
435 && fe->atv_demod->drv->init_sys)
436 ret = fe->atv_demod->drv->init_sys(fe->atv_demod, sys);
437 if (fe->tuner
438 && fe->tuner->drv
439 && fe->tuner->drv->init_sys)
440 ret = fe->tuner->drv->init_sys(fe->tuner, sys);
441
442 if (ret != 0) {
443 pr_error("init system, %d fail, ret %d\n", sys, ret);
444 goto end;
445 }
446
447 fe->set_property = fe->fe->ops.set_property;
448 fe->get_property = fe->fe->ops.get_property;
449
450 strcpy(fe->fe->ops.info.name, "amlogic dvb frontend");
451 fe->sys = sys;
452 pr_dbg("set mode ok\n");
453
454end:
455 fe->fe->ops.set_property = aml_fe_set_property;
456 fe->fe->ops.get_property = aml_fe_get_property;
457
458 return 0;
459}
460
461static const char *aml_fe_dev_type_str(struct aml_fe_dev *dev)
462{
463 switch (dev->type) {
464 case AM_DEV_TUNER:
465 return "tuner";
466 case AM_DEV_ATV_DEMOD:
467 return "atv_demod";
468 case AM_DEV_DTV_DEMOD:
469 return "dtv_demod";
470 }
471
472 return "";
473}
474
475static void aml_fe_property_name(struct aml_fe_dev *dev, const char *name,
476 char *buf)
477{
478 const char *tstr;
479
480 tstr = aml_fe_dev_type_str(dev);
481
482 if (name)
483 sprintf(buf, "%s%d_%s", tstr, dev->dev_id, name);
484 else
485 sprintf(buf, "%s%d", tstr, dev->dev_id);
486}
487
488int aml_fe_of_property_string(struct aml_fe_dev *dev,
489 const char *name, const char **str)
490{
491 struct platform_device *pdev = dev->man->pdev;
492 //char buf[128];
493 int r;
494
495 //aml_fe_property_name(dev, name, buf);
496 pr_error("start find resource: \"%s\" --\n", name);
497 r = of_property_read_string(pdev->dev.of_node, name, str);
498 if (r)
499 pr_error("cannot find resource: \"%s\"\n", name);
500
501 return r;
502}
503EXPORT_SYMBOL(aml_fe_of_property_string);
504
505int aml_fe_of_property_u32(struct aml_fe_dev *dev,
506 const char *name, u32 *v)
507{
508 struct platform_device *pdev = dev->man->pdev;
509 //char buf[128];
510 int r;
511
512 //aml_fe_property_name(dev, name, buf);
513 r = of_property_read_u32(pdev->dev.of_node, name, v);
514 if (r)
515 pr_error("cannot find resource \"%s\"\n", name);
516
517 return r;
518}
519EXPORT_SYMBOL(aml_fe_of_property_u32);
520
521static int aml_fe_dev_init(struct aml_fe_man *man,
522 enum aml_fe_dev_type_t type,
523 struct aml_fe_dev *dev,
524 int id)
525{
526 struct aml_fe_drv **list = aml_get_fe_drv_list(type);
527 struct aml_fe_drv *drv;
528 unsigned long flags;
529 char buf[128];
530 const char *str;
531 char *name = NULL;
532 u32 value;
533 int ret;
534 struct device_node *node;
535
536 dev->man = man;
537 dev->dev_id = id;
538 dev->type = type;
539 dev->drv = NULL;
540 dev->fe = NULL;
541 dev->priv_data = NULL;
542
543 memset(buf, 0, 128);
544 name = NULL;
545 aml_fe_property_name(dev, name, buf);
546 pr_dbg("get string: %s\n", buf);
547 ret = aml_fe_of_property_string(dev, buf, &str);
548 if (ret) {
549 pr_dbg("get string: %s error\n", buf);
550 return 0;
551 }
552
553
554 spin_lock_irqsave(&lock, flags);
555
556 for (drv = *list; drv; drv = drv->next)
557 if (!strcmp(drv->name, str))
558 break;
559
560 if (dev->drv != drv) {
561 if (dev->drv) {
562 dev->drv->ref--;
563 if (dev->drv->owner)
564 module_put(dev->drv->owner);
565 }
566 if (drv) {
567 drv->ref++;
568 if (drv->owner)
569 try_module_get(drv->owner);
570 }
571 dev->drv = drv;
572 }
573
574 spin_unlock_irqrestore(&lock, flags);
575
576 if (drv) {
577 pr_inf("found driver: %s\n", str);
578 } else {
579 pr_err("cannot find driver: %s\n", str);
580 return -1;
581 }
582 /*get i2c adap and i2c addr*/
583 memset(buf, 0, 128);
584 name = "i2c_adap";
585 aml_fe_property_name(dev, name, buf);
586 pr_dbg("get u32: %s\n", buf);
587 //ret = aml_fe_of_property_u32(dev, buf, &value);
588 node = of_parse_phandle(dev->man->pdev->dev.of_node, buf, 0);
589 if (node) {
590 dev->i2c_adap = of_find_i2c_adapter_by_node(node);
591 pr_inf("%s:[%p]\n", buf, dev->i2c_adap);
592 of_node_put(node);
593 } else {
594 dev->i2c_adap_id = -1;
595 pr_error("cannot find resource \"%s\"\n", buf);
596 }
597 memset(buf, 0, 128);
598 name = "i2c_addr";
599 aml_fe_property_name(dev, name, buf);
600 pr_dbg("get u32: %s\n", buf);
601 ret = aml_fe_of_property_u32(dev, buf, &value);
602 if (!ret) {
603 dev->i2c_addr = value;
604 pr_inf("%s: %d\n", buf, dev->i2c_addr);
605 } else {
606 dev->i2c_addr = -1;
607 pr_error("cannot find resource \"%s\"\n", buf);
608 }
609 /*get i2c reset and reset value*/
610 memset(buf, 0, 128);
611 name = "reset_gpio";
612 aml_fe_property_name(dev, name, buf);
613 pr_dbg("get string: %s\n", buf);
614 ret = aml_fe_of_property_string(dev, buf, &str);
615 if (!ret) {
616 dev->reset_gpio =
617 of_get_named_gpio_flags(dev->man->pdev->dev.of_node,
618 buf, 0, NULL);
619 pr_inf("%s: %s\n", buf, str);
620 } else {
621 dev->reset_gpio = -1;
622 pr_error("cannot find resource \"%s\"\n", buf);
623 }
624 memset(buf, 0, 128);
625 name = "reset_value";
626 aml_fe_property_name(dev, name, buf);
627 pr_dbg("get u32: %s\n", buf);
628 ret = aml_fe_of_property_u32(dev, buf, &value);
629 if (!ret) {
630 dev->reset_value = value;
631 pr_inf("%s: %d\n", buf, dev->reset_value);
632 } else {
633 dev->reset_value = -1;
634 }
635
636 if (dev->drv && dev->drv->init) {
637 int ret;
638
639 ret = dev->drv->init(dev);
640 if (ret != 0) {
641 dev->drv = NULL;
642 pr_error("[aml_fe..]%s error.\n", __func__);
643 return ret;
644 }
645 }
646
647 return 0;
648}
649
650static int aml_fe_dev_release(struct aml_fe_dev *dev)
651{
652 if (dev->drv) {
653 if (dev->drv->owner)
654 module_put(dev->drv->owner);
655 dev->drv->ref--;
656 if (dev->drv->release)
657 dev->drv->release(dev);
658 }
659
660 dev->drv = NULL;
661 return 0;
662}
663
664static void aml_fe_man_run(struct aml_fe *fe)
665{
666 if (fe->init)
667 return;
668
669 if (fe->tuner && fe->tuner->drv)
670 fe->init = 1;
671
672 if (fe->atv_demod && fe->atv_demod->drv)
673 fe->init = 1;
674
675 if (fe->dtv_demod && fe->dtv_demod->drv)
676 fe->init = 1;
677
678 if (fe->init) {
679 struct aml_dvb *dvb = fe->man->dvb;
680 int reg = 1;
681 int ret;
682 int id;
683
684 spin_lock_init(&fe->slock);
685
686 fe->sys = SYS_UNDEFINED;
687
688 pr_dbg("fe: %p\n", fe);
689
690 for (id = 0; id < FE_DEV_COUNT; id++) {
691 struct aml_fe *prev_fe = &fe_man.fe[id];
692
693 if (prev_fe == fe)
694 continue;
695 if (prev_fe->init && (prev_fe->dev_id == fe->dev_id)) {
696 reg = 0;
697 break;
698 }
699 }
700
701 fe->fe = &fe_man.dev[fe->dev_id];
702 if (reg) {
703 fe->fe->demodulator_priv = fe;
704 fe->fe->ops.set_property = aml_fe_set_property;
705 fe->fe->ops.get_property = aml_fe_set_property;
706 }
707
708 if (fe->tuner)
709 fe->tuner->fe = fe;
710 if (fe->atv_demod)
711 fe->atv_demod->fe = fe;
712 if (fe->dtv_demod)
713 fe->dtv_demod->fe = fe;
714
715 ret = dvb_register_frontend(&dvb->dvb_adapter, fe->fe);
716 if (ret) {
717 pr_error("register fe%d failed\n", fe->dev_id);
718 return;
719 }
720 }
721}
722
723static void fe_property_name(struct aml_fe *fe, const char *name,
724 char *buf)
725{
726 if (name)
727 sprintf(buf, "fe%d_%s", fe->dev_id, name);
728 else
729 sprintf(buf, "fe%d", fe->dev_id);
730}
731
732static int fe_of_property_u32(struct aml_fe *fe,
733 const char *name, u32 *v)
734{
735 struct platform_device *pdev = fe->man->pdev;
736 char buf[128];
737 int r;
738
739 fe_property_name(fe, name, buf);
740 r = of_property_read_u32(pdev->dev.of_node, buf, v);
741 if (r)
742 pr_error("cannot find resource \"%s\"\n", buf);
743
744 return r;
745}
746
747static int aml_fe_man_init(struct aml_fe_man *man, struct aml_fe *fe, int id)
748{
749 u32 value;
750 int ret;
751
752 fe->sys = SYS_UNDEFINED;
753 fe->man = man;
754 fe->dev_id = id;
755 fe->init = 0;
756 fe->ts = AM_TS_SRC_TS0;
757 fe->work_running = 0;
758 fe->work_q = NULL;
759 fe->tuner = NULL;
760 fe->atv_demod = NULL;
761 fe->dtv_demod = NULL;
762 fe->do_work = NULL;
763 fe->get_property = NULL;
764 fe->set_property = NULL;
765
766 init_waitqueue_head(&fe->wait_q);
767 spin_lock_init(&fe->slock);
768
769 ret = fe_of_property_u32(fe, "tuner", &value);
770 if (!ret) {
771 id = value;
772
773 if ((id < 0) || (id >= FE_DEV_COUNT) || !fe_man.tuner[id].drv) {
774 pr_error("invalid tuner device id %d\n", id);
775 return -1;
776 }
777
778 fe->tuner = &fe_man.tuner[id];
779 fe_man.tuner[id].fe = fe;
780 }
781
782 ret = fe_of_property_u32(fe, "atv_demod", &value);
783 if (!ret) {
784 id = value;
785
786 if ((id < 0) ||
787 (id >= FE_DEV_COUNT) ||
788 !fe_man.atv_demod[id].drv) {
789 pr_error("invalid ATV demod device id %d\n", id);
790 return -1;
791 }
792
793 fe->atv_demod = &fe_man.atv_demod[id];
794 fe_man.atv_demod[id].fe = fe;
795 }
796
797 ret = fe_of_property_u32(fe, "dtv_demod", &value);
798 if (!ret) {
799 id = value;
800
801 if ((id < 0) ||
802 (id >= FE_DEV_COUNT) ||
803 !fe_man.dtv_demod[id].drv) {
804 pr_error("invalid DTV demod device id %d\n", id);
805 return -1;
806 }
807
808 fe->dtv_demod = &fe_man.dtv_demod[id];
809 fe_man.dtv_demod[id].fe = fe;
810 }
811
812 ret = fe_of_property_u32(fe, "ts", &value);
813 if (!ret) {
814 enum aml_ts_source_t ts = AM_TS_SRC_TS0;
815
816 switch (value) {
817 case 0:
818 ts = AM_TS_SRC_TS0;
819 break;
820 case 1:
821 ts = AM_TS_SRC_TS1;
822 break;
823 case 2:
824 ts = AM_TS_SRC_TS2;
825 break;
826 default:
827 break;
828 }
829
830 fe->ts = ts;
831 }
832
833 ret = fe_of_property_u32(fe, "dev", &value);
834 if (!ret) {
835 id = value;
836
837 if ((id >= 0) && (id < FE_DEV_COUNT))
838 fe->dev_id = id;
839 else
840 fe->dev_id = 0;
841 }
842
843 aml_fe_man_run(fe);
844
845 return 0;
846}
847
848static int aml_fe_man_release(struct aml_fe *fe)
849{
850 if (fe->init) {
851 aml_fe_cancel_work(fe);
852
853 if (fe->work_q)
854 destroy_workqueue(fe->work_q);
855
856 aml_fe_set_sys(fe->fe, SYS_UNDEFINED);
857 dvb_unregister_frontend(fe->fe);
858 dvb_frontend_detach(fe->fe);
859
860 fe->tuner = NULL;
861 fe->atv_demod = NULL;
862 fe->dtv_demod = NULL;
863 fe->init = 0;
864 }
865
866 return 0;
867}
868
869void aml_fe_set_pdata(struct aml_fe_dev *dev, void *pdata)
870{
871 dev->priv_data = pdata;
872}
873EXPORT_SYMBOL(aml_fe_set_pdata);
874
875void *aml_fe_get_pdata(struct aml_fe_dev *dev)
876{
877 return dev->priv_data;
878}
879EXPORT_SYMBOL(aml_fe_get_pdata);
880
881static void aml_fe_do_work(struct work_struct *work)
882{
883 struct aml_fe *fe;
884
885 fe = container_of(work, struct aml_fe, work);
886
887 if (fe->do_work)
888 fe->do_work(fe);
889
890 fe->work_running = 0;
891}
892
893void aml_fe_schedule_work(struct aml_fe *fe, void(*func)(struct aml_fe *fe))
894{
895 if (fe->work_running)
896 cancel_work_sync(&fe->work);
897
898 fe->work_running = 1;
899 fe->do_work = func;
900
901 if (!fe->work_q) {
902 fe->work_q = create_singlethread_workqueue("amlfe");
903 INIT_WORK(&fe->work, aml_fe_do_work);
904 }
905
906 queue_work(fe->work_q, &fe->work);
907}
908EXPORT_SYMBOL(aml_fe_schedule_work);
909
910void aml_fe_cancel_work(struct aml_fe *fe)
911{
912 if (fe->work_running) {
913 fe->work_running = 0;
914 cancel_work_sync(&fe->work);
915 }
916
917 fe->do_work = NULL;
918}
919EXPORT_SYMBOL(aml_fe_cancel_work);
920
921
922int aml_fe_work_cancelled(struct aml_fe *fe)
923{
924 return fe->work_running ? 0 : 1;
925}
926EXPORT_SYMBOL(aml_fe_work_cancelled);
927
928int aml_fe_work_sleep(struct aml_fe *fe, unsigned long delay)
929{
930 wait_event_interruptible_timeout(fe->wait_q, !fe->work_running, delay);
931 return aml_fe_work_cancelled(fe);
932}
933EXPORT_SYMBOL(aml_fe_work_sleep);
934
935static ssize_t tuner_name_show(struct class *cls, struct class_attribute *attr,
936 char *buf)
937{
938 size_t len = 0;
939 struct aml_fe_drv *drv;
940 unsigned long flags;
941
942 struct aml_fe_drv **list = aml_get_fe_drv_list(AM_DEV_TUNER);
943
944 spin_lock_irqsave(&lock, flags);
945 for (drv = *list; drv; drv = drv->next)
946 len += sprintf(buf + len, "%s\n", drv->name);
947 spin_unlock_irqrestore(&lock, flags);
948 return len;
949}
950
951static ssize_t atv_demod_name_show(struct class *cls,
952 struct class_attribute *attr, char *buf)
953{
954 size_t len = 0;
955 struct aml_fe_drv *drv;
956 unsigned long flags;
957
958 struct aml_fe_drv **list = aml_get_fe_drv_list(AM_DEV_ATV_DEMOD);
959
960 spin_lock_irqsave(&lock, flags);
961 for (drv = *list; drv; drv = drv->next)
962 len += sprintf(buf + len, "%s\n", drv->name);
963 spin_unlock_irqrestore(&lock, flags);
964 return len;
965}
966
967static ssize_t dtv_demod_name_show(struct class *cls,
968 struct class_attribute *attr, char *buf)
969{
970 size_t len = 0;
971 struct aml_fe_drv *drv;
972 unsigned long flags;
973
974 struct aml_fe_drv **list = aml_get_fe_drv_list(AM_DEV_DTV_DEMOD);
975
976 spin_lock_irqsave(&lock, flags);
977 for (drv = *list; drv; drv = drv->next)
978 len += sprintf(buf + len, "%s\n", drv->name);
979 spin_unlock_irqrestore(&lock, flags);
980 return len;
981}
982
983static ssize_t setting_show(struct class *cls, struct class_attribute *attr,
984 char *buf)
985{
986 int r, total = 0;
987 int i;
988 struct aml_fe_man *fm = &fe_man;
989
990 r = sprintf(buf, "tuner:\n");
991 buf += r;
992 total += r;
993 for (i = 0; i < FE_DEV_COUNT; i++) {
994 struct aml_fe_dev *dev = &fm->tuner[i];
995
996 if (dev->drv) {
997 r = sprintf(buf, "\t%d: %s\n", i, dev->drv->name);
998 buf += r;
999 total += r;
1000 }
1001 }
1002
1003 r = sprintf(buf, "atv_demod:\n");
1004 buf += r;
1005 total += r;
1006 for (i = 0; i < FE_DEV_COUNT; i++) {
1007 struct aml_fe_dev *dev = &fm->atv_demod[i];
1008
1009 if (dev->drv) {
1010 r = sprintf(buf, "\t%d: %s\n", i, dev->drv->name);
1011 buf += r;
1012 total += r;
1013 }
1014 }
1015
1016 r = sprintf(buf, "dtv_demod:\n");
1017 buf += r;
1018 total += r;
1019 for (i = 0; i < FE_DEV_COUNT; i++) {
1020 struct aml_fe_dev *dev = &fm->dtv_demod[i];
1021
1022 if (dev->drv) {
1023 r = sprintf(buf, "\t%d: %s\n", i, dev->drv->name);
1024 buf += r;
1025 total += r;
1026 }
1027 }
1028
1029 r = sprintf(buf, "frontend:\n");
1030 buf += r;
1031 total += r;
1032 for (i = 0; i < FE_DEV_COUNT; i++) {
1033 struct aml_fe *fe = &fm->fe[i];
1034
1035 r = sprintf(buf,
1036 "\t%d: %s device: %d ts: %d tuner: %s atv_demod: %s dtv_demod: %s\n",
1037 i, fe->init ? "enabled" : "disabled", fe->dev_id,
1038 fe->ts, fe->tuner ? fe->tuner->drv->name : "none",
1039 fe->atv_demod ? fe->atv_demod->drv->name : "none",
1040 fe->dtv_demod ? fe->dtv_demod->drv->name : "none");
1041 buf += r;
1042 total += r;
1043 }
1044
1045 return total;
1046}
1047
1048static void reset_drv(int id, enum aml_fe_dev_type_t type, const char *name)
1049{
1050 struct aml_fe_man *fm = &fe_man;
1051 struct aml_fe_drv **list;
1052 struct aml_fe_drv **pdrv;
1053 struct aml_fe_drv *drv;
1054 struct aml_fe_drv *old;
1055
1056 if ((id < 0) || (id >= FE_DEV_COUNT))
1057 return;
1058
1059 if (fm->fe[id].init) {
1060 pr_error("cannot reset driver when the device is inused\n");
1061 return;
1062 }
1063
1064 list = aml_get_fe_drv_list(type);
1065 for (drv = *list; drv; drv = drv->next)
1066 if (!strcmp(drv->name, name))
1067 break;
1068
1069 switch (type) {
1070 case AM_DEV_TUNER:
1071 pdrv = &fm->tuner[id].drv;
1072 break;
1073 case AM_DEV_ATV_DEMOD:
1074 pdrv = &fm->atv_demod[id].drv;
1075 break;
1076 case AM_DEV_DTV_DEMOD:
1077 pdrv = &fm->dtv_demod[id].drv;
1078 break;
1079 default:
1080 return;
1081 }
1082
1083 old = *pdrv;
1084 if (old == drv)
1085 return;
1086
1087 if (old) {
1088 old->ref--;
1089 if (old->owner)
1090 module_put(old->owner);
1091 }
1092
1093 if (drv) {
1094 drv->ref++;
1095 if (drv->owner)
1096 try_module_get(drv->owner);
1097 }
1098
1099 *pdrv = drv;
1100}
1101
1102static ssize_t setting_store(struct class *class, struct class_attribute *attr,
1103 const char *buf, size_t size)
1104{
1105 struct aml_fe_man *fm = &fe_man;
1106 int id, val;
1107 char dev_name[32];
1108 unsigned long flags;
1109
1110 spin_lock_irqsave(&lock, flags);
1111
1112 if (sscanf(buf, "tuner %i driver %s", &id, dev_name) == 2) {
1113 reset_drv(id, AM_DEV_TUNER, dev_name);
1114 } else if (sscanf(buf, "atv_demod %i driver %s", &id, dev_name) == 2) {
1115 reset_drv(id, AM_DEV_ATV_DEMOD, dev_name);
1116 } else if (sscanf(buf, "dtv_demod %i driver %s", &id, dev_name) == 2) {
1117 reset_drv(id, AM_DEV_DTV_DEMOD, dev_name);
1118 } else if (sscanf(buf, "frontend %i device %i", &id, &val) == 2) {
1119 if ((id >= 0) && (id < FE_DEV_COUNT))
1120 fm->fe[id].dev_id = val;
1121 } else if (sscanf(buf, "frontend %i ts %i", &id, &val) == 2) {
1122 if ((id >= 0) && (id < FE_DEV_COUNT))
1123 fm->fe[id].ts = val;
1124 } else if (sscanf(buf, "frontend %i tuner %i", &id, &val) == 2) {
1125 if ((id >= 0) && (id < FE_DEV_COUNT) && (val >= 0)
1126 && (val < FE_DEV_COUNT) && fm->tuner[val].drv)
1127 fm->fe[id].tuner = &fm->tuner[val];
1128 } else if (sscanf(buf, "frontend %i atv_demod %i", &id, &val) == 2) {
1129 if ((id >= 0) && (id < FE_DEV_COUNT) && (val >= 0)
1130 && (val < FE_DEV_COUNT) && fm->atv_demod[val].drv)
1131 fm->fe[id].atv_demod = &fm->atv_demod[val];
1132 } else if (sscanf(buf, "frontend %i dtv_demod %i", &id, &val) == 2) {
1133 if ((id >= 0) && (id < FE_DEV_COUNT) && (val >= 0)
1134 && (val < FE_DEV_COUNT) && fm->dtv_demod[val].drv)
1135 fm->fe[id].dtv_demod = &fm->dtv_demod[val];
1136 }
1137
1138 spin_unlock_irqrestore(&lock, flags);
1139
1140 if (sscanf(buf, "enable %i", &id) == 1) {
1141 if ((id >= 0) && (id < FE_DEV_COUNT))
1142 aml_fe_man_run(&fm->fe[id]);
1143 } else if (sscanf(buf, "disable %i", &id) == 1) {
1144 if ((id >= 0) && (id < FE_DEV_COUNT))
1145 aml_fe_man_release(&fm->fe[id]);
1146 } else if (strstr(buf, "autoload")) {
1147 for (id = 0; id < FE_DEV_COUNT; id++) {
1148 aml_fe_dev_init(fm, AM_DEV_TUNER,
1149 &fm->tuner[id], id);
1150 aml_fe_dev_init(fm, AM_DEV_ATV_DEMOD,
1151 &fm->atv_demod[id], id);
1152 aml_fe_dev_init(fm, AM_DEV_DTV_DEMOD,
1153 &fm->dtv_demod[id], id);
1154 }
1155
1156 for (id = 0; id < FE_DEV_COUNT; id++)
1157 aml_fe_man_init(fm, &fm->fe[id], id);
1158 } else if (strstr(buf, "disableall")) {
1159 for (id = 0; id < FE_DEV_COUNT; id++)
1160 aml_fe_man_release(&fm->fe[id]);
1161
1162 for (id = 0; id < FE_DEV_COUNT; id++) {
1163 aml_fe_dev_release(&fm->dtv_demod[id]);
1164 aml_fe_dev_release(&fm->atv_demod[id]);
1165 aml_fe_dev_release(&fm->tuner[id]);
1166 }
1167 }
1168
1169 return size;
1170}
1171
1172static ssize_t aml_fe_show_suspended_flag(struct class *class,
1173 struct class_attribute *attr,
1174 char *buf)
1175{
1176 ssize_t ret = 0;
1177
1178 ret = sprintf(buf, "%ld\n", aml_fe_suspended);
1179
1180 return ret;
1181}
1182
1183static ssize_t aml_fe_store_suspended_flag(struct class *class,
1184 struct class_attribute *attr,
1185 const char *buf, size_t size)
1186{
1187 /*aml_fe_suspended = simple_strtol(buf, 0, 0); */
1188 int ret = kstrtol(buf, 0, &aml_fe_suspended);
1189
1190 if (ret)
1191 return ret;
1192 return size;
1193}
1194
1195static struct class_attribute aml_fe_cls_attrs[] = {
1196 __ATTR(tuner_name,
1197 0644,
1198 tuner_name_show, NULL),
1199 __ATTR(atv_demod_name,
1200 0644,
1201 atv_demod_name_show, NULL),
1202 __ATTR(dtv_demod_name,
1203 0644,
1204 dtv_demod_name_show, NULL),
1205 __ATTR(setting,
1206 0644,
1207 setting_show, setting_store),
1208 __ATTR(aml_fe_suspended_flag,
1209 0644,
1210 aml_fe_show_suspended_flag,
1211 aml_fe_store_suspended_flag),
1212 __ATTR_NULL
1213};
1214
1215static struct class aml_fe_class = {
1216 .name = "amlfe",
1217 .class_attrs = aml_fe_cls_attrs,
1218};
1219
1220static int aml_fe_probe(struct platform_device *pdev)
1221{
1222 struct aml_dvb *dvb = aml_get_dvb_device();
1223 int i;
1224
1225 fe_man.dvb = dvb;
1226 fe_man.pdev = pdev;
1227
1228 platform_set_drvdata(pdev, &fe_man);
1229
1230 for (i = 0; i < FE_DEV_COUNT; i++) {
1231 if (aml_fe_dev_init(&fe_man,
1232 AM_DEV_TUNER,
1233 &fe_man.tuner[i], i) < 0)
1234 goto probe_end;
1235
1236 if (aml_fe_dev_init(&fe_man,
1237 AM_DEV_ATV_DEMOD,
1238 &fe_man.atv_demod[i], i) < 0)
1239 goto probe_end;
1240
1241 if (aml_fe_dev_init(&fe_man,
1242 AM_DEV_DTV_DEMOD,
1243 &fe_man.dtv_demod[i], i) < 0)
1244 goto probe_end;
1245 }
1246
1247 for (i = 0; i < FE_DEV_COUNT; i++) {
1248 if (aml_fe_man_init(&fe_man, &fe_man.fe[i], i) < 0)
1249 goto probe_end;
1250 }
1251
1252 probe_end:
1253
1254 fe_man.pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
1255
1256 if (class_register(&aml_fe_class) < 0)
1257 pr_error("[aml_fe..] register class error\n");
1258
1259 pr_dbg("[aml_fe..] probe ok.\n");
1260
1261 return 0;
1262}
1263
1264static int aml_fe_remove(struct platform_device *pdev)
1265{
1266 struct aml_fe_man *fe_man = platform_get_drvdata(pdev);
1267 int i;
1268
1269 if (fe_man) {
1270 platform_set_drvdata(pdev, NULL);
1271
1272 for (i = 0; i < FE_DEV_COUNT; i++)
1273 aml_fe_man_release(&fe_man->fe[i]);
1274 for (i = 0; i < FE_DEV_COUNT; i++) {
1275 aml_fe_dev_release(&fe_man->dtv_demod[i]);
1276 aml_fe_dev_release(&fe_man->atv_demod[i]);
1277 aml_fe_dev_release(&fe_man->tuner[i]);
1278 }
1279
1280 if (fe_man->pinctrl)
1281 devm_pinctrl_put(fe_man->pinctrl);
1282 }
1283
1284 class_unregister(&aml_fe_class);
1285
1286 return 0;
1287}
1288
1289static int aml_fe_suspend(struct platform_device *dev, pm_message_t state)
1290{
1291 int i;
1292
1293 for (i = 0; i < FE_DEV_COUNT; i++) {
1294 struct aml_fe *fe = &fe_man.fe[i];
1295
1296 if (fe->tuner && fe->tuner->drv->suspend)
1297 fe->tuner->drv->suspend(fe->tuner);
1298
1299 if (fe->atv_demod && fe->atv_demod->drv->suspend)
1300 fe->atv_demod->drv->suspend(fe->atv_demod);
1301
1302 if (fe->dtv_demod && fe->dtv_demod->drv->suspend)
1303 fe->dtv_demod->drv->suspend(fe->dtv_demod);
1304 }
1305
1306 aml_fe_suspended = 1;
1307
1308 return 0;
1309}
1310
1311static int aml_fe_resume(struct platform_device *dev)
1312{
1313 int i;
1314
1315 aml_fe_suspended = 0;
1316
1317 for (i = 0; i < FE_DEV_COUNT; i++) {
1318 struct aml_fe *fe = &fe_man.fe[i];
1319
1320 if (fe->tuner && fe->tuner->drv->resume)
1321 fe->tuner->drv->resume(fe->tuner);
1322
1323 if (fe->atv_demod && fe->atv_demod->drv->resume)
1324 fe->atv_demod->drv->resume(fe->atv_demod);
1325
1326 if (fe->dtv_demod && fe->dtv_demod->drv->resume)
1327 fe->dtv_demod->drv->resume(fe->dtv_demod);
1328 }
1329
1330 return 0;
1331}
1332
1333#ifdef CONFIG_OF
1334static const struct of_device_id aml_fe_dt_match[] = {
1335 {
1336 .compatible = "amlogic, dvbfe",
1337 },
1338 {},
1339};
1340#endif /*CONFIG_OF */
1341
1342static struct platform_driver aml_fe_driver = {
1343 .probe = aml_fe_probe,
1344 .remove = aml_fe_remove,
1345 .suspend = aml_fe_suspend,
1346 .resume = aml_fe_resume,
1347 .driver = {
1348 .name = "amlogic-dvb-fe",
1349 .owner = THIS_MODULE,
1350#ifdef CONFIG_OF
1351 .of_match_table = aml_fe_dt_match,
1352#endif
1353 }
1354};
1355
1356static int __init aml_fe_init(void)
1357{
1358 return platform_driver_register(&aml_fe_driver);
1359}
1360
1361static void __exit aml_fe_exit(void)
1362{
1363 platform_driver_unregister(&aml_fe_driver);
1364}
1365
1366module_init(aml_fe_init);
1367module_exit(aml_fe_exit);
1368
1369MODULE_LICENSE("GPL");
1370MODULE_DESCRIPTION("amlogic frontend driver");
1371MODULE_AUTHOR("L+#= +0=1");
1372
1373