summaryrefslogtreecommitdiff
path: root/drivers/stream_input/tv_frontend/dtv_demod/aml_demod.c (plain)
blob: 7ccdfae3e1a902f8f1d3d5476dffafac7fd7636f
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#include <linux/init.h>
21#include <linux/types.h>
22#include <linux/ioport.h>
23#include <linux/platform_device.h>
24#include <linux/version.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/spinlock.h>
28#include <linux/interrupt.h>
29#include <linux/fs.h>
30#include <linux/string.h>
31#include <linux/io.h>
32#include <linux/mm.h>
33#include <linux/major.h>
34#include <linux/err.h>
35#include <linux/mutex.h>
36#include <linux/ctype.h>
37#include <linux/sched.h>
38#include <linux/poll.h>
39#include <linux/i2c.h>
40#include <linux/delay.h>
41/* #include <mach/am_regs.h> */
42#include <linux/device.h>
43#include <linux/cdev.h>
44
45/* #include <asm/fiq.h> */
46#include <linux/uaccess.h>
47#include <linux/dvb/aml_demod.h>
48#include "demod_func.h"
49
50#include <linux/slab.h>
51#ifdef CONFIG_COMPAT
52#include <linux/compat.h>
53#endif
54/*#include "sdio/sdio_init.h"*/
55#define DRIVER_NAME "aml_demod"
56#define MODULE_NAME "aml_demod"
57#define DEVICE_NAME "aml_demod"
58#define DEVICE_UI_NAME "aml_demod_ui"
59
60#define pr_dbg(a ...) \
61 do { \
62 if (1) { \
63 printk(a); \
64 } \
65 } while (0)
66
67
68const char aml_demod_dev_id[] = "aml_demod";
69
70/*#ifndef CONFIG_AM_DEMOD_DVBAPI
71 * static struct aml_demod_i2c demod_i2c;
72 * static struct aml_demod_sta demod_sta;
73 * #else
74 * extern struct aml_demod_i2c demod_i2c;
75 * extern struct aml_demod_sta demod_sta;
76 #endif
77*/
78
79static struct aml_demod_i2c demod_i2c;
80static struct aml_demod_sta demod_sta;
81static int read_start;
82
83int sdio_read_ddr(unsigned long sdio_addr, unsigned long byte_count,
84 unsigned char *data_buf)
85{
86 return 0;
87}
88
89int sdio_write_ddr(unsigned long sdio_addr, unsigned long byte_count,
90 unsigned char *data_buf)
91{
92 return 0;
93}
94
95int read_reg(int addr)
96{
97 addr = addr + DEMOD_BASE;
98 return apb_read_reg(addr);
99}
100
101void wait_capture(int cap_cur_addr, int depth_MB, int start)
102{
103 int readfirst;
104 int tmp;
105 int time_out;
106 int last = 0x90000000;
107
108 time_out = readfirst = 0;
109 tmp = depth_MB << 20;
110 while (tmp && (time_out < 1000)) { /*10seconds time out */
111 time_out = time_out + 1;
112 msleep(20);
113 readfirst = app_apb_read_reg(cap_cur_addr);
114 if ((last - readfirst) > 0)
115 tmp = 0;
116 else
117 last = readfirst;
118 /* usleep(1000); */
119 /* readsecond= app_apb_read_reg(cap_cur_addr); */
120
121 /* if((readsecond-start)>tmp) */
122/* tmp=0;*/
123/* if((readsecond-readfirst)<0) // turn around*/
124/* tmp=0;*/
125 pr_dbg("First %x = [%08x],[%08x]%x\n", cap_cur_addr, readfirst,
126 last, (last - readfirst));
127/* printf("Second %x = [%08x]\n",cap_cur_addr, readsecond);*/
128 msleep(20);
129 }
130 read_start = readfirst + 0x40000000;
131 pr_dbg("read_start is %x\n", read_start);
132}
133
134int cap_adc_data(struct aml_cap_data *cap)
135{
136 int tmp;
137 int tb_depth;
138
139 pr_dbg("capture ADC\n ");
140 /* printf("set mem_start (you can read in kernel start log
141 * (memstart is ).(hex) : ");
142 */
143 /* scanf("%x",&tmp);*/
144 tmp = 0x94400000;
145 app_apb_write_reg(0x9d, cap->cap_addr);
146 app_apb_write_reg(0x9e, cap->cap_addr + cap->cap_size * 0x100000);
147 /*0x8000000-128m, 0x400000-4m */
148 read_start = tmp + 0x40000000;
149 /*printf("set afifo rate. (hex)(adc_clk/demod_clk)*256+2 : "); //
150 * (adc_clk/demod_clk)*256+2
151 */
152 /* scanf("%x",&tmp); */
153 cap->cap_afifo = 0x60;
154 app_apb_write_reg(0x15, 0x18715f2);
155 app_apb_write_reg(0x15, (app_apb_read_reg(0x15) & 0xfff00fff) |
156 ((cap->cap_afifo & 0xff) << 12)); /* set afifo */
157 app_apb_write_reg(0x9b, 0x1c9); /* capture ADC 10bits */
158 app_apb_write_reg(0x7f, 0x00008000); /* enable testbus 0x8000 */
159
160 tb_depth = cap->cap_size; /*127; */
161 tmp = 9;
162 app_apb_write_reg(0x9b, (app_apb_read_reg(0x9b) & ~0x1f) | tmp);
163 /* set testbus width */
164
165 tmp = 0x100000;
166 app_apb_write_reg(0x9c, tmp); /* by ADC data enable */
167 /* printf("Set test mode. (0 is normal ,1 is testmode) : "); //0 */
168 /* scanf("%d",&tmp); */
169 tmp = 0;
170 if (tmp == 1)
171 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 10));
172 /* set test mode; */
173 else
174 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 10));
175 /* close test mode; */
176
177 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 9));
178 /* close cap; */
179 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 9));
180 /* open cap; */
181
182 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 7));
183 /* close tb; */
184 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 7));
185 /* open tb; */
186
187 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 5));
188 /* close intlv; */
189
190 app_apb_write_reg(0x303, 0x8); /* open dc_arbit */
191
192 tmp = 0;
193 if (tmp)
194 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 5));
195 /* open intlv; */
196
197 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) & ~(1 << 8));
198 /* go tb; */
199
200 wait_capture(0x9f, tb_depth, app_apb_read_reg(0x9d));
201
202 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 8));
203 /* stop tb; */
204 app_apb_write_reg(0x9b, app_apb_read_reg(0x9b) | (1 << 7));
205 /* close tb; */
206 return 0;
207}
208
209static DECLARE_WAIT_QUEUE_HEAD(lock_wq);
210
211static ssize_t aml_demod_info(struct class *cla,
212 struct class_attribute *attr, char *buf)
213{
214 return 0;
215}
216
217static struct class_attribute aml_demod_class_attrs[] = {
218 __ATTR(info,
219 0644,
220 aml_demod_info,
221 NULL),
222 __ATTR_NULL
223};
224
225static struct class aml_demod_class = {
226 .name = "aml_demod",
227 .class_attrs = aml_demod_class_attrs,
228};
229
230#if 0
231
232static irqreturn_t aml_demod_isr(int irq, void *dev_id)
233{
234 if (demod_sta.dvb_mode == 0) {
235 /*dvbc_isr(&demod_sta); */
236 if (dvbc_isr_islock()) {
237 pr_dbg("sync4\n");
238 /*if (waitqueue_active(&lock_wq))
239 *wake_up_interruptible(&lock_wq);
240 */
241 }
242 } else {
243 dvbt_isr(&demod_sta);
244 }
245
246 return IRQ_HANDLED;
247}
248#endif
249
250static int aml_demod_open(struct inode *inode, struct file *file)
251{
252 pr_dbg("Amlogic Demod DVB-T/C Open\n");
253 return 0;
254}
255
256static int aml_demod_release(struct inode *inode, struct file *file)
257{
258 pr_dbg("Amlogic Demod DVB-T/C Release\n");
259 return 0;
260}
261
262#if 0
263static int amdemod_islock(void)
264{
265 struct aml_demod_sts demod_sts;
266
267 if (demod_sta.dvb_mode == 0) {
268 dvbc_status(&demod_sta, &demod_i2c, &demod_sts);
269 return demod_sts.ch_sts & 0x1;
270 } else if (demod_sta.dvb_mode == 1) {
271 dvbt_status(&demod_sta, &demod_i2c, &demod_sts);
272 return demod_sts.ch_sts >> 12 & 0x1;
273 }
274 return 0;
275}
276#endif
277
278void mem_read(struct aml_demod_mem *arg)
279{
280 int data;
281 int addr;
282
283 addr = arg->addr;
284 data = arg->dat;
285/* memcpy(mem_buf[addr],data,1);*/
286 pr_dbg("[addr %x] data is %x\n", addr, data);
287}
288static long aml_demod_ioctl(struct file *file,
289 unsigned int cmd, unsigned long arg)
290{
291 int strength = 0;
292 struct dvb_frontend *dvbfe;
293 struct aml_tuner_sys *tuner;
294
295 switch (cmd) {
296 case AML_DEMOD_GET_RSSI:
297 pr_dbg("Ioctl Demod GET_RSSI.\n");
298 dvbfe = get_si2177_tuner();
299 if (dvbfe != NULL)
300 strength = dvbfe->ops.tuner_ops.get_strength(dvbfe);
301 pr_dbg("[si2177] strength is %d\n", strength - 256);
302 if (strength < 0)
303 strength = 0 - strength;
304 tuner = (struct aml_tuner_sys *)arg;
305 tuner->rssi = strength;
306 break;
307
308 case AML_DEMOD_SET_TUNER:
309 pr_dbg("Ioctl Demod Set Tuner.\n");
310 dvbfe = get_si2177_tuner();
311 if (dvbfe != NULL)
312 dvbfe->ops.tuner_ops.set_tuner(dvbfe, &demod_sta,
313 &demod_i2c,
314 (struct aml_tuner_sys *)
315 arg);
316 break;
317
318 case AML_DEMOD_SET_SYS:
319 pr_dbg("Ioctl Demod Set System\n");
320 demod_set_sys(&demod_sta, &demod_i2c,
321 (struct aml_demod_sys *)arg);
322 break;
323
324 case AML_DEMOD_GET_SYS:
325 pr_dbg("Ioctl Demod Get System\n");
326
327 /*demod_get_sys(&demod_i2c, (struct aml_demod_sys *)arg); */
328 break;
329
330 case AML_DEMOD_TEST:
331 pr_dbg("Ioctl Demod Test. It is blank now\n");
332 /*demod_msr_clk(13); */
333 /*demod_msr_clk(14); */
334 /*demod_calc_clk(&demod_sta); */
335 break;
336
337 case AML_DEMOD_TURN_ON:
338 pr_dbg("Ioctl Demod Turn ON.It is blank now\n");
339 /*demod_turn_on(&demod_sta, (struct aml_demod_sys *)arg); */
340 break;
341
342 case AML_DEMOD_TURN_OFF:
343 pr_dbg("Ioctl Demod Turn OFF.It is blank now\n");
344 /*demod_turn_off(&demod_sta, (struct aml_demod_sys *)arg); */
345 break;
346
347 case AML_DEMOD_DVBC_SET_CH:
348 pr_dbg("Ioctl DVB-C Set Channel.\n");
349 dvbc_set_ch(&demod_sta, &demod_i2c,
350 (struct aml_demod_dvbc *)arg);
351 break;
352
353 case AML_DEMOD_DVBC_GET_CH:
354 /* pr_dbg("Ioctl DVB-C Get Channel. It is blank\n"); */
355 dvbc_status(&demod_sta, &demod_i2c,
356 (struct aml_demod_sts *)arg);
357 break;
358 case AML_DEMOD_DVBC_TEST:
359 pr_dbg("Ioctl DVB-C Test. It is blank\n");
360 /*dvbc_get_test_out(0xb, 1000, (u32 *)arg); */
361 break;
362 case AML_DEMOD_DVBT_SET_CH:
363 pr_dbg("Ioctl DVB-T Set Channel\n");
364 dvbt_set_ch(&demod_sta, &demod_i2c,
365 (struct aml_demod_dvbt *)arg);
366 break;
367
368 case AML_DEMOD_DVBT_GET_CH:
369 pr_dbg("Ioctl DVB-T Get Channel\n");
370 /*dvbt_status(&demod_sta, &demod_i2c,
371 * (struct aml_demod_sts *)arg);
372 */
373 break;
374
375 case AML_DEMOD_DVBT_TEST:
376 pr_dbg("Ioctl DVB-T Test. It is blank\n");
377 /*dvbt_get_test_out(0x1e, 1000, (u32 *)arg); */
378 break;
379
380 case AML_DEMOD_DTMB_SET_CH:
381 dtmb_set_ch(&demod_sta, &demod_i2c,
382 (struct aml_demod_dtmb *)arg);
383 break;
384
385 case AML_DEMOD_DTMB_GET_CH:
386 break;
387
388 case AML_DEMOD_DTMB_TEST:
389 break;
390
391 case AML_DEMOD_ATSC_SET_CH:
392 atsc_set_ch(&demod_sta, &demod_i2c,
393 (struct aml_demod_atsc *)arg);
394 break;
395
396 case AML_DEMOD_ATSC_GET_CH:
397 check_atsc_fsm_status();
398 break;
399
400 case AML_DEMOD_ATSC_TEST:
401 break;
402
403 case AML_DEMOD_SET_REG:
404 /* pr_dbg("Ioctl Set Register\n"); */
405 demod_set_reg((struct aml_demod_reg *)arg);
406 break;
407
408 case AML_DEMOD_GET_REG:
409 /* pr_dbg("Ioctl Get Register\n"); */
410 demod_get_reg((struct aml_demod_reg *)arg);
411 break;
412
413/* case AML_DEMOD_SET_REGS: */
414/* break; */
415
416/* case AML_DEMOD_GET_REGS: */
417/* break; */
418
419 case AML_DEMOD_RESET_MEM:
420 pr_dbg("set mem ok\n");
421 break;
422
423 case AML_DEMOD_READ_MEM:
424 break;
425 case AML_DEMOD_SET_MEM:
426 /*step=(struct aml_demod_mem)arg;
427 * pr_dbg("[%x]0x%x------------------\n",i,mem_buf[step]);
428 * for(i=step;i<1024-1;i++){
429 * pr_dbg("0x%x,",mem_buf[i]);
430 * }
431 */
432 mem_read((struct aml_demod_mem *)arg);
433 break;
434
435 case AML_DEMOD_ATSC_IRQ:
436 atsc_read_iqr_reg();
437 break;
438
439 default:
440 pr_dbg("Enter Default ! 0x%X\n", cmd);
441/* pr_dbg("AML_DEMOD_GET_REGS=0x%08X\n", AML_DEMOD_GET_REGS); */
442/* pr_dbg("AML_DEMOD_SET_REGS=0x%08X\n", AML_DEMOD_SET_REGS); */
443 return -EINVAL;
444 }
445
446 return 0;
447}
448
449#ifdef CONFIG_COMPAT
450
451static long aml_demod_compat_ioctl(struct file *file, unsigned int cmd,
452 ulong arg)
453{
454 return aml_demod_ioctl(file, cmd, (ulong)compat_ptr(arg));
455}
456
457#endif
458
459
460static const struct file_operations aml_demod_fops = {
461 .owner = THIS_MODULE,
462 .open = aml_demod_open,
463 .release = aml_demod_release,
464 .unlocked_ioctl = aml_demod_ioctl,
465#ifdef CONFIG_COMPAT
466 .compat_ioctl = aml_demod_compat_ioctl,
467#endif
468};
469
470static int aml_demod_ui_open(struct inode *inode, struct file *file)
471{
472 pr_dbg("Amlogic aml_demod_ui_open Open\n");
473 return 0;
474}
475
476static int aml_demod_ui_release(struct inode *inode, struct file *file)
477{
478 pr_dbg("Amlogic aml_demod_ui_open Release\n");
479 return 0;
480}
481char buf_all[100];
482static ssize_t aml_demod_ui_read(struct file *file, char __user *buf,
483 size_t count, loff_t *ppos)
484{
485 char *capture_buf = buf_all;
486 int res = 0;
487
488 if (count >= 4 * 1024 * 1024)
489 count = 4 * 1024 * 1024;
490 else if (count == 0)
491 return 0;
492
493 res = copy_to_user((void *)buf, (char *)capture_buf, count);
494 if (res < 0) {
495 pr_dbg("[aml_demod_ui_read]res is %d", res);
496 return res;
497 }
498
499 return count;
500}
501
502static ssize_t aml_demod_ui_write(struct file *file, const char *buf,
503 size_t count, loff_t *ppos)
504{
505 return 0;
506}
507
508static struct device *aml_demod_ui_dev;
509static dev_t aml_demod_devno_ui;
510static struct cdev *aml_demod_cdevp_ui;
511static const struct file_operations aml_demod_ui_fops = {
512 .owner = THIS_MODULE,
513 .open = aml_demod_ui_open,
514 .release = aml_demod_ui_release,
515 .read = aml_demod_ui_read,
516 .write = aml_demod_ui_write,
517 /* .unlocked_ioctl = aml_demod_ui_ioctl, */
518};
519
520#if 0
521static ssize_t aml_demod_ui_info(struct class *cla,
522 struct class_attribute *attr, char *buf)
523{
524 return 0;
525}
526
527static struct class_attribute aml_demod_ui_class_attrs[] = {
528 __ATTR(info,
529 0644,
530 aml_demod_ui_info,
531 NULL),
532 __ATTR_NULL
533};
534#endif
535
536static struct class aml_demod_ui_class = {
537 .name = "aml_demod_ui",
538/* .class_attrs = aml_demod_ui_class_attrs,*/
539};
540
541int aml_demod_ui_init(void)
542{
543 int r = 0;
544
545 r = class_register(&aml_demod_ui_class);
546 if (r) {
547 pr_dbg("create aml_demod class fail\r\n");
548 class_unregister(&aml_demod_ui_class);
549 return r;
550 }
551
552 r = alloc_chrdev_region(&aml_demod_devno_ui, 0, 1, DEVICE_UI_NAME);
553 if (r < 0) {
554 pr_dbg("aml_demod_ui: failed to alloc major number\n");
555 r = -ENODEV;
556 unregister_chrdev_region(aml_demod_devno_ui, 1);
557 class_unregister(&aml_demod_ui_class);
558 return r;
559 }
560
561 aml_demod_cdevp_ui = kmalloc(sizeof(struct cdev), GFP_KERNEL);
562 if (!aml_demod_cdevp_ui) {
563 r = -ENOMEM;
564 unregister_chrdev_region(aml_demod_devno_ui, 1);
565 kfree(aml_demod_cdevp_ui);
566 class_unregister(&aml_demod_ui_class);
567 return r;
568 }
569 /* connect the file operation with cdev */
570 cdev_init(aml_demod_cdevp_ui, &aml_demod_ui_fops);
571 aml_demod_cdevp_ui->owner = THIS_MODULE;
572 /* connect the major/minor number to cdev */
573 r = cdev_add(aml_demod_cdevp_ui, aml_demod_devno_ui, 1);
574 if (r) {
575 pr_dbg("aml_demod_ui:failed to add cdev\n");
576 unregister_chrdev_region(aml_demod_devno_ui, 1);
577 cdev_del(aml_demod_cdevp_ui);
578 kfree(aml_demod_cdevp_ui);
579 class_unregister(&aml_demod_ui_class);
580 return r;
581 }
582
583 aml_demod_ui_dev = device_create(&aml_demod_ui_class, NULL,
584 MKDEV(MAJOR(aml_demod_devno_ui), 0),
585 NULL, DEVICE_UI_NAME);
586
587 if (IS_ERR(aml_demod_ui_dev)) {
588 pr_dbg("Can't create aml_demod device\n");
589 unregister_chrdev_region(aml_demod_devno_ui, 1);
590 cdev_del(aml_demod_cdevp_ui);
591 kfree(aml_demod_cdevp_ui);
592 class_unregister(&aml_demod_ui_class);
593 return r;
594 }
595
596 return r;
597}
598
599void aml_demod_exit_ui(void)
600{
601 unregister_chrdev_region(aml_demod_devno_ui, 1);
602 cdev_del(aml_demod_cdevp_ui);
603 kfree(aml_demod_cdevp_ui);
604 class_unregister(&aml_demod_ui_class);
605}
606
607static struct device *aml_demod_dev;
608static dev_t aml_demod_devno;
609static struct cdev *aml_demod_cdevp;
610
611#ifdef CONFIG_AM_DEMOD_DVBAPI
612int aml_demod_init(void)
613#else
614static int __init aml_demod_init(void)
615#endif
616{
617 int r = 0;
618
619 pr_dbg("Amlogic Demod DVB-T/C DebugIF Init\n");
620
621 init_waitqueue_head(&lock_wq);
622
623 /* hook demod isr */
624 /* r = request_irq(INT_DEMOD, &aml_demod_isr,
625 * IRQF_SHARED, "aml_demod",
626 * (void *)aml_demod_dev_id);
627 * if (r) {
628 * pr_dbg("aml_demod irq register error.\n");
629 * r = -ENOENT;
630 * goto err0;
631 * }
632 */
633
634 /* sysfs node creation */
635 r = class_register(&aml_demod_class);
636 if (r) {
637 pr_dbg("create aml_demod class fail\r\n");
638 goto err1;
639 }
640
641 r = alloc_chrdev_region(&aml_demod_devno, 0, 1, DEVICE_NAME);
642 if (r < 0) {
643 pr_dbg("aml_demod: failed to alloc major number\n");
644 r = -ENODEV;
645 goto err2;
646 }
647
648 aml_demod_cdevp = kmalloc(sizeof(struct cdev), GFP_KERNEL);
649 if (!aml_demod_cdevp) {
650 r = -ENOMEM;
651 goto err3;
652 }
653 /* connect the file operation with cdev */
654 cdev_init(aml_demod_cdevp, &aml_demod_fops);
655 aml_demod_cdevp->owner = THIS_MODULE;
656 /* connect the major/minor number to cdev */
657 r = cdev_add(aml_demod_cdevp, aml_demod_devno, 1);
658 if (r) {
659 pr_dbg("aml_demod:failed to add cdev\n");
660 goto err4;
661 }
662
663 aml_demod_dev = device_create(&aml_demod_class, NULL,
664 MKDEV(MAJOR(aml_demod_devno), 0), NULL,
665 DEVICE_NAME);
666
667 if (IS_ERR(aml_demod_dev)) {
668 pr_dbg("Can't create aml_demod device\n");
669 goto err5;
670 }
671 pr_dbg("Amlogic Demod DVB-T/C DebugIF Init ok----------------\n");
672#if defined(CONFIG_AM_AMDEMOD_FPGA_VER) && !defined(CONFIG_AM_DEMOD_DVBAPI)
673 pr_dbg("sdio_init\n");
674 sdio_init();
675#endif
676 aml_demod_ui_init();
677
678 return 0;
679
680err5:
681 cdev_del(aml_demod_cdevp);
682err4:
683 kfree(aml_demod_cdevp);
684
685err3:
686 unregister_chrdev_region(aml_demod_devno, 1);
687
688err2:
689/* free_irq(INT_DEMOD, (void *)aml_demod_dev_id);*/
690
691err1:
692 class_unregister(&aml_demod_class);
693
694/* err0:*/
695 return r;
696}
697
698#ifdef CONFIG_AM_DEMOD_DVBAPI
699void aml_demod_exit(void)
700#else
701static void __exit aml_demod_exit(void)
702#endif
703{
704 pr_dbg("Amlogic Demod DVB-T/C DebugIF Exit\n");
705
706 unregister_chrdev_region(aml_demod_devno, 1);
707 device_destroy(&aml_demod_class, MKDEV(MAJOR(aml_demod_devno), 0));
708 cdev_del(aml_demod_cdevp);
709 kfree(aml_demod_cdevp);
710
711 /* free_irq(INT_DEMOD, (void *)aml_demod_dev_id); */
712
713 class_unregister(&aml_demod_class);
714
715 aml_demod_exit_ui();
716}
717
718#ifndef CONFIG_AM_DEMOD_DVBAPI
719module_init(aml_demod_init);
720module_exit(aml_demod_exit);
721
722MODULE_LICENSE("GPL");
723/*MODULE_AUTHOR(DRV_AUTHOR);*/
724/*MODULE_DESCRIPTION(DRV_DESC);*/
725#endif
726