fc8150.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. #include <linux/miscdevice.h>
  2. #include <linux/interrupt.h>
  3. #include <linux/kthread.h>
  4. #include <linux/poll.h>
  5. #include <linux/vmalloc.h>
  6. #include <linux/irq.h>
  7. #include <linux/delay.h>
  8. #include <linux/slab.h>
  9. #include <linux/gpio.h>
  10. #include <linux/export.h>
  11. #include <linux/io.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/module.h>
  14. #include <media/isdbt_pdata.h>
  15. #include <mach/gpio.h>
  16. #include <linux/clk.h>
  17. #if defined(CONFIG_ISDBT_ANT_DET)
  18. #include <linux/wakelock.h>
  19. #include <linux/input.h>
  20. #endif
  21. #include "fc8150.h"
  22. #include "bbm.h"
  23. #include "fci_oal.h"
  24. #include "fci_tun.h"
  25. #include "fc8150_regs.h"
  26. #include "fc8150_isr.h"
  27. #include "fci_hal.h"
  28. #define FEATURE_GLOBAL_MEM
  29. #ifdef FEATURE_GLOBAL_MEM
  30. struct ISDBT_OPEN_INFO_T hOpen_Val;
  31. u8 ringbuffer[128*1024];
  32. #endif
  33. #if defined(CONFIG_ISDBT_ANT_DET)
  34. static struct wake_lock isdbt_ant_wlock;
  35. #endif
  36. struct ISDBT_INIT_INFO_T *hInit;
  37. #define RING_BUFFER_SIZE (128 * 1024) /* kmalloc max 128k */
  38. /* GPIO(RESET & INTRRUPT) Setting */
  39. #define FC8150_NAME "isdbt"
  40. #define FEATURE_TS_CHECK
  41. #ifdef FEATURE_TS_CHECK
  42. u32 check_cnt_size;
  43. #define MAX_DEMUX 2
  44. /*
  45. * Sync Byte 0xb8
  46. */
  47. #define SYNC_BYTE_INVERSION
  48. struct pid_info {
  49. unsigned long count;
  50. unsigned long discontinuity;
  51. unsigned long continuity;
  52. };
  53. struct demux_info {
  54. struct pid_info pids[8192];
  55. unsigned long ts_packet_c;
  56. unsigned long malformed_packet_c;
  57. unsigned long tot_scraped_sz;
  58. unsigned long packet_no;
  59. unsigned long sync_err;
  60. unsigned long sync_err_set;
  61. };
  62. static int is_sync(unsigned char *p)
  63. {
  64. int syncword = p[0];
  65. #ifdef SYNC_BYTE_INVERSION
  66. if(0x47 == syncword || 0xb8 == syncword)
  67. return 1;
  68. #else
  69. if(0x47 == syncword)
  70. return 1;
  71. #endif
  72. return 0;
  73. }
  74. static struct demux_info demux[MAX_DEMUX];
  75. void print_pkt_log(void)
  76. {
  77. unsigned long i=0;
  78. PRINTF(NULL, "\nPKT_TOT : %d, SYNC_ERR : %d, SYNC_ERR_BIT : %d \
  79. , ERR_PKT : %d \n"
  80. , demux[0].ts_packet_c, demux[0].sync_err
  81. , demux[0].sync_err_set, demux[0].malformed_packet_c);
  82. for (i = 0; i < 8192; i++) {
  83. if(demux[0].pids[i].count>0)
  84. PRINTF(NULL, "PID : %d, TOT_PKT : %d\
  85. , DISCONTINUITY : %d \n"
  86. , i, demux[0].pids[i].count
  87. , demux[0].pids[i].discontinuity);
  88. }
  89. }
  90. int put_ts_packet(int no, unsigned char *packet, int sz)
  91. {
  92. unsigned char* p;
  93. int transport_error_indicator, pid, payload_unit_start_indicator;
  94. int continuity_counter, last_continuity_counter;
  95. int i;
  96. if((sz % 188)) {
  97. PRINTF(NULL, "L : %d", sz);
  98. } else {
  99. for(i = 0; i < sz; i += 188) {
  100. p = packet + i;
  101. pid = ((p[1] & 0x1f) << 8) + p[2];
  102. demux[no].ts_packet_c++;
  103. if(!is_sync(packet + i)) {
  104. PRINTF(NULL, "S ");
  105. demux[no].sync_err++;
  106. if(0x80==(p[1] & 0x80))
  107. demux[no].sync_err_set++;
  108. PRINTF(NULL, "0x%x, 0x%x, 0x%x, 0x%x \n"
  109. , *p, *(p+1), *(p+2), *(p+3));
  110. continue;
  111. }
  112. transport_error_indicator = (p[1] & 0x80) >> 7;
  113. if(1 == transport_error_indicator) {
  114. demux[no].malformed_packet_c++;
  115. continue;
  116. }
  117. payload_unit_start_indicator = (p[1] & 0x40) >> 6;
  118. demux[no].pids[pid].count++;
  119. continuity_counter = p[3] & 0x0f;
  120. if(demux[no].pids[pid].continuity == -1) {
  121. demux[no].pids[pid].continuity
  122. = continuity_counter;
  123. } else {
  124. last_continuity_counter
  125. = demux[no].pids[pid].continuity;
  126. demux[no].pids[pid].continuity
  127. = continuity_counter;
  128. if (((last_continuity_counter + 1) & 0x0f)
  129. != continuity_counter) {
  130. demux[no].pids[pid].discontinuity++;
  131. }
  132. }
  133. }
  134. }
  135. return 0;
  136. }
  137. void create_tspacket_anal(void)
  138. {
  139. int n, i;
  140. for(n = 0; n < MAX_DEMUX; n++) {
  141. memset((void*)&demux[n], 0, sizeof(demux[n]));
  142. for (i = 0; i < 8192; i++)
  143. demux[n].pids[i].continuity = -1;
  144. }
  145. }
  146. #endif
  147. /*
  148. #define GPIO_ISDBT_IRQ 0x24
  149. #define GPIO_ISDBT_PWR_EN 1
  150. #define GPIO_ISDBT_RST 2
  151. */
  152. enum ISDBT_MODE driver_mode = ISDBT_POWEROFF;
  153. static DEFINE_MUTEX(ringbuffer_lock);
  154. #ifdef CONFIG_MACH_JAVA_SS_BAFFINLITE
  155. #define GPIO_ISDBT_RST_N 17
  156. #define GPIO_ISDBT_EN 90 // In Roy, ISDBT_EN pin is changed to GPIO 58
  157. #define GPIO_ISDBT_INT 16
  158. #else
  159. #define GPIO_ISDBT_RST_N 100
  160. #define GPIO_ISDBT_EN 16 // In Roy, ISDBT_EN pin is changed to GPIO 58
  161. #define GPIO_ISDBT_INT 17
  162. #endif
  163. #define GPIO_ISDBT_IRQ gpio_to_irq(GPIO_ISDBT_INT)
  164. #define GPIO_ISDBT_IRQ_FC8150 GPIO_ISDBT_INT
  165. #define GPIO_ISDBT_PWR_EN_FC8150 GPIO_ISDBT_EN
  166. #define GPIO_ISDBT_RST_FC8150 GPIO_ISDBT_RST_N
  167. static DECLARE_WAIT_QUEUE_HEAD(isdbt_isr_wait);
  168. static u8 isdbt_isr_sig;
  169. static struct task_struct *isdbt_kthread;
  170. static struct isdbt_platform_data gpio_cfg;
  171. static struct clk *isdbt_clk=NULL;
  172. static unsigned long clkrate = 0;
  173. static irqreturn_t isdbt_irq(int irq, void *dev_id)
  174. {
  175. isdbt_isr_sig = 1;
  176. wake_up_interruptible(&isdbt_isr_wait);
  177. return IRQ_HANDLED;
  178. }
  179. int isdbt_hw_setting(void)
  180. {
  181. int err;
  182. PRINTF(0, "isdbt_hw_setting\n");
  183. err = gpio_request(GPIO_ISDBT_PWR_EN_FC8150, "isdbt_en");
  184. if (err) {
  185. PRINTF(0, "isdbt_hw_setting: Couldn't request isdbt_en\n");
  186. goto gpio_isdbt_en;
  187. }
  188. gpio_direction_output(GPIO_ISDBT_PWR_EN_FC8150, 0);
  189. err = gpio_request(GPIO_ISDBT_RST_FC8150, "isdbt_rst");
  190. if (err) {
  191. PRINTF(0, "isdbt_hw_setting: Couldn't request isdbt_rst\n");
  192. goto gpio_isdbt_rst;
  193. }
  194. gpio_direction_output(GPIO_ISDBT_RST_FC8150, 1);
  195. err = gpio_request(GPIO_ISDBT_IRQ_FC8150, "isdbt_irq");
  196. if (err) {
  197. PRINTF(0, "isdbt_hw_setting: Couldn't request isdbt_irq\n");
  198. goto gpio_isdbt_rst;
  199. }
  200. gpio_direction_input(GPIO_ISDBT_IRQ_FC8150);
  201. #if 1 // Not a broadcom/LSI model
  202. err = request_irq(gpio_to_irq(GPIO_ISDBT_IRQ_FC8150), isdbt_irq
  203. , IRQF_DISABLED | IRQF_TRIGGER_RISING, FC8150_NAME, NULL);
  204. // disable_irq(GPIO_ISDBT_IRQ_FC8150);
  205. #else
  206. err = request_irq(GPIO_ISDBT_IRQ, isdbt_irq
  207. , IRQF_DISABLED | IRQF_TRIGGER_RISING, FC8150_NAME, NULL);
  208. #endif
  209. if (err < 0) {
  210. PRINTF(0, "isdbt_hw_setting: couldn't request gpio");
  211. PRINTF(0, "interrupt %d reason(%d)\n"
  212. , gpio_to_irq(GPIO_ISDBT_IRQ_FC8150), err);
  213. goto request_isdbt_irq;
  214. }
  215. return 0;
  216. request_isdbt_irq:
  217. gpio_free(GPIO_ISDBT_IRQ_FC8150);
  218. gpio_isdbt_rst:
  219. gpio_free(GPIO_ISDBT_PWR_EN_FC8150);
  220. gpio_isdbt_en:
  221. return err;
  222. }
  223. /*POWER_ON & HW_RESET & INTERRUPT_CLEAR */
  224. void isdbt_hw_init(void)
  225. {
  226. int i = 0;
  227. while (driver_mode == ISDBT_DATAREAD) {
  228. msWait(100);
  229. if (i++ > 5)
  230. break;
  231. }
  232. PRINTF(0, "isdbt_hw_init\n");
  233. gpio_set_value(GPIO_ISDBT_PWR_EN_FC8150, 1);
  234. gpio_set_value(GPIO_ISDBT_RST_FC8150, 1);
  235. mdelay(5);
  236. gpio_set_value(GPIO_ISDBT_RST_FC8150, 0);
  237. mdelay(2);
  238. gpio_set_value(GPIO_ISDBT_RST_FC8150, 1);
  239. mdelay(20);
  240. driver_mode = ISDBT_POWERON;
  241. }
  242. /*POWER_OFF */
  243. void isdbt_hw_deinit(void)
  244. {
  245. PRINTF(0, "isdbt_hw_deinit\n");
  246. driver_mode = ISDBT_POWEROFF;
  247. gpio_set_value(GPIO_ISDBT_RST_FC8150, 0);
  248. gpio_set_value(GPIO_ISDBT_PWR_EN_FC8150, 0);
  249. }
  250. int data_callback(u32 hDevice, u8 *data, int len)
  251. {
  252. struct ISDBT_INIT_INFO_T *hInit;
  253. struct list_head *temp;
  254. hInit = (struct ISDBT_INIT_INFO_T *)hDevice;
  255. list_for_each(temp, &(hInit->hHead))
  256. {
  257. struct ISDBT_OPEN_INFO_T *hOpen;
  258. hOpen = list_entry(temp, struct ISDBT_OPEN_INFO_T, hList);
  259. if (hOpen->isdbttype == TS_TYPE) {
  260. mutex_lock(&ringbuffer_lock);
  261. if (fci_ringbuffer_free(&hOpen->RingBuffer) < len) {
  262. /*PRINTF(hDevice, "f"); */
  263. /* return 0 */;
  264. FCI_RINGBUFFER_SKIP(&hOpen->RingBuffer, len);
  265. }
  266. fci_ringbuffer_write(&hOpen->RingBuffer, data, len);
  267. wake_up_interruptible(&(hOpen->RingBuffer.queue));
  268. mutex_unlock(&ringbuffer_lock);
  269. }
  270. }
  271. return 0;
  272. }
  273. static int isdbt_thread(void *hDevice)
  274. {
  275. struct ISDBT_INIT_INFO_T *hInit = (struct ISDBT_INIT_INFO_T *)hDevice;
  276. set_user_nice(current, -20);
  277. PRINTF(hInit, "isdbt_kthread enter\n");
  278. BBM_TS_CALLBACK_REGISTER((u32)hInit, data_callback);
  279. while (1) {
  280. wait_event_interruptible(isdbt_isr_wait,
  281. isdbt_isr_sig || kthread_should_stop());
  282. if (driver_mode == ISDBT_POWERON) {
  283. driver_mode = ISDBT_DATAREAD;
  284. BBM_ISR(hInit);
  285. driver_mode = ISDBT_POWERON;
  286. }
  287. isdbt_isr_sig = 0;
  288. if (kthread_should_stop())
  289. break;
  290. }
  291. BBM_TS_CALLBACK_DEREGISTER();
  292. PRINTF(hInit, "isdbt_kthread exit\n");
  293. return 0;
  294. }
  295. const struct file_operations isdbt_fops = {
  296. .owner = THIS_MODULE,
  297. .unlocked_ioctl = isdbt_ioctl,
  298. .open = isdbt_open,
  299. .read = isdbt_read,
  300. .release = isdbt_release,
  301. };
  302. static struct miscdevice fc8150_misc_device = {
  303. .minor = MISC_DYNAMIC_MINOR,
  304. .name = FC8150_NAME,
  305. .fops = &isdbt_fops,
  306. };
  307. int isdbt_open(struct inode *inode, struct file *filp)
  308. {
  309. struct ISDBT_OPEN_INFO_T *hOpen;
  310. PRINTF(hInit, "isdbt open\n");
  311. #ifdef FEATURE_GLOBAL_MEM
  312. hOpen = &hOpen_Val;
  313. hOpen->buf = &ringbuffer[0];
  314. #else
  315. hOpen = kmalloc(sizeof(struct ISDBT_OPEN_INFO_T), GFP_KERNEL);
  316. hOpen->buf = kmalloc(RING_BUFFER_SIZE, GFP_KERNEL);
  317. #endif
  318. hOpen->isdbttype = 0;
  319. list_add(&(hOpen->hList), &(hInit->hHead));
  320. hOpen->hInit = (HANDLE *)hInit;
  321. if (hOpen->buf == NULL) {
  322. PRINTF(hInit, "ring buffer malloc error\n");
  323. return -ENOMEM;
  324. }
  325. fci_ringbuffer_init(&hOpen->RingBuffer, hOpen->buf, RING_BUFFER_SIZE);
  326. filp->private_data = hOpen;
  327. return 0;
  328. }
  329. ssize_t isdbt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
  330. {
  331. s32 avail;
  332. s32 non_blocking = filp->f_flags & O_NONBLOCK;
  333. struct ISDBT_OPEN_INFO_T *hOpen
  334. = (struct ISDBT_OPEN_INFO_T *)filp->private_data;
  335. struct fci_ringbuffer *cibuf = &hOpen->RingBuffer;
  336. ssize_t len, read_len = 0;
  337. if (!cibuf->data || !count) {
  338. /*PRINTF(hInit, " return 0\n"); */
  339. return 0;
  340. }
  341. if (non_blocking && (fci_ringbuffer_empty(cibuf))) {
  342. /*PRINTF(hInit, "return EWOULDBLOCK\n"); */
  343. return -EWOULDBLOCK;
  344. }
  345. if (wait_event_interruptible(cibuf->queue,
  346. !fci_ringbuffer_empty(cibuf))) {
  347. PRINTF(hInit, "return ERESTARTSYS\n");
  348. return -ERESTARTSYS;
  349. }
  350. mutex_lock(&ringbuffer_lock);
  351. avail = fci_ringbuffer_avail(cibuf);
  352. if (count >= avail)
  353. len = avail;
  354. else
  355. len = count - (count % 188);
  356. read_len = fci_ringbuffer_read_user(cibuf, buf, len);
  357. mutex_unlock(&ringbuffer_lock);
  358. return read_len;
  359. }
  360. int isdbt_release(struct inode *inode, struct file *filp)
  361. {
  362. struct ISDBT_OPEN_INFO_T *hOpen;
  363. PRINTF(hInit, "isdbt_release\n");
  364. hOpen = filp->private_data;
  365. hOpen->isdbttype = 0;
  366. list_del(&(hOpen->hList));
  367. #ifndef FEATURE_GLOBAL_MEM
  368. kfree(hOpen->buf);
  369. kfree(hOpen);
  370. #endif
  371. return 0;
  372. }
  373. int fc8150_if_test(void)
  374. {
  375. int res = 0;
  376. int i;
  377. u16 wdata = 0;
  378. u32 ldata = 0;
  379. u8 data = 0;
  380. u8 temp = 0;
  381. PRINTF(0, "fc8150_if_test Start!!!\n");
  382. for (i = 0 ; i < 100 ; i++) {
  383. BBM_BYTE_WRITE(0, 0xa4, i & 0xff);
  384. BBM_BYTE_READ(0, 0xa4, &data);
  385. if ((i & 0xff) != data) {
  386. PRINTF(0, "fc8150_if_btest! i=0x%x, data=0x%x\n"
  387. , i & 0xff, data);
  388. res = 1;
  389. }
  390. }
  391. for (i = 0 ; i < 100 ; i++) {
  392. BBM_WORD_WRITE(0, 0xa4, i & 0xffff);
  393. BBM_WORD_READ(0, 0xa4, &wdata);
  394. if ((i & 0xffff) != wdata) {
  395. PRINTF(0, "fc8150_if_wtest! i=0x%x, data=0x%x\n"
  396. , i & 0xffff, wdata);
  397. res = 1;
  398. }
  399. }
  400. for (i = 0 ; i < 100 ; i++) {
  401. BBM_LONG_WRITE(0, 0xa4, i & 0xffffffff);
  402. BBM_LONG_READ(0, 0xa4, &ldata);
  403. if ((i & 0xffffffff) != ldata) {
  404. PRINTF(0, "fc8150_if_ltest! i=0x%x, data=0x%x\n"
  405. , i & 0xffffffff, ldata);
  406. res = 1;
  407. }
  408. }
  409. for (i = 0 ; i < 100 ; i++) {
  410. temp = i & 0xff;
  411. BBM_TUNER_WRITE(NULL, 0x52, 0x01, &temp, 0x01);
  412. BBM_TUNER_READ(NULL, 0x52, 0x01, &data, 0x01);
  413. if ((i & 0xff) != data)
  414. PRINTF(0, "FC8150 tuner test (0x%x,0x%x)\n"
  415. , i & 0xff, data);
  416. }
  417. PRINTF(0, "fc8150_if_test End!!!\n");
  418. return res;
  419. }
  420. void isdbt_isr_check(HANDLE hDevice)
  421. {
  422. u8 isr_time = 0;
  423. BBM_WRITE(hDevice, BBM_BUF_INT, 0x00);
  424. while (isr_time < 10) {
  425. if (!isdbt_isr_sig)
  426. break;
  427. msWait(10);
  428. isr_time++;
  429. }
  430. }
  431. long isdbt_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  432. {
  433. s32 res = BBM_NOK;
  434. s32 err = 0;
  435. s32 size = 0;
  436. struct ISDBT_OPEN_INFO_T *hOpen;
  437. struct ioctl_info info;
  438. if (_IOC_TYPE(cmd) != IOCTL_MAGIC)
  439. return -EINVAL;
  440. if (_IOC_NR(cmd) >= IOCTL_MAXNR)
  441. return -EINVAL;
  442. hOpen = filp->private_data;
  443. size = _IOC_SIZE(cmd);
  444. switch (cmd) {
  445. case IOCTL_ISDBT_RESET:
  446. PRINTF(hInit, "IOCTL_ISDBT_RESET, !\n");
  447. res = BBM_RESET(hInit);
  448. PRINTF(hInit, "FC8150 BBM_RESET \n");
  449. break;
  450. case IOCTL_ISDBT_INIT:
  451. res = BBM_I2C_INIT(hInit, FCI_I2C_TYPE);
  452. res |= BBM_PROBE(hInit);
  453. if (res) {
  454. PRINTF(hInit, "[FC8150] Initialize Fail \n");
  455. break;
  456. }
  457. res |= BBM_INIT(hInit);
  458. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_INIT res : 0x%x \n", res);
  459. break;
  460. case IOCTL_ISDBT_BYTE_READ:
  461. err = copy_from_user((void *)&info, (void *)arg, size);
  462. res = BBM_BYTE_READ(hInit, (u16)info.buff[0]
  463. , (u8 *)(&info.buff[1]));
  464. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_BYTE_READ reg : 0x%x dat : 0x%x\n"
  465. , (u16)info.buff[0], info.buff[1]);
  466. err |= copy_to_user((void *)arg, (void *)&info, size);
  467. break;
  468. case IOCTL_ISDBT_WORD_READ:
  469. err = copy_from_user((void *)&info, (void *)arg, size);
  470. res = BBM_WORD_READ(hInit, (u16)info.buff[0]
  471. , (u16 *)(&info.buff[1]));
  472. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_WORD_READ reg : 0x%x dat : 0x%x\n"
  473. , (u16)info.buff[0], info.buff[1]);
  474. err |= copy_to_user((void *)arg, (void *)&info, size);
  475. break;
  476. case IOCTL_ISDBT_LONG_READ:
  477. err = copy_from_user((void *)&info, (void *)arg, size);
  478. res = BBM_LONG_READ(hInit, (u16)info.buff[0]
  479. , (u32 *)(&info.buff[1]));
  480. PRINTF(hInit, "[FC8150] BBM_LONG_READ reg : 0x%x dat : 0x%x\n"
  481. , (u16)info.buff[0], info.buff[1]);
  482. err |= copy_to_user((void *)arg, (void *)&info, size);
  483. break;
  484. case IOCTL_ISDBT_BULK_READ:
  485. err = copy_from_user((void *)&info, (void *)arg, size);
  486. res = BBM_BULK_READ(hInit, (u16)info.buff[0]
  487. , (u8 *)(&info.buff[2]), info.buff[1]);
  488. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_BULK_READ reg : 0x%x size : 0x%x\n"
  489. , (u16)info.buff[0], info.buff[1]);
  490. err |= copy_to_user((void *)arg, (void *)&info, size);
  491. break;
  492. case IOCTL_ISDBT_BYTE_WRITE:
  493. err = copy_from_user((void *)&info, (void *)arg, size);
  494. res = BBM_BYTE_WRITE(hInit, (u16)info.buff[0]
  495. , (u8)info.buff[1]);
  496. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_BYTE_WRITE reg : 0x%x dat : 0x%x\n"
  497. , (u16)info.buff[0], (u8)info.buff[1]);
  498. break;
  499. case IOCTL_ISDBT_WORD_WRITE:
  500. err = copy_from_user((void *)&info, (void *)arg, size);
  501. res = BBM_WORD_WRITE(hInit, (u16)info.buff[0]
  502. , (u16)info.buff[1]);
  503. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_WORD_WRITE reg : 0x%x dat : 0x%x\n"
  504. , (u16)info.buff[0], (u16)info.buff[1]);
  505. break;
  506. case IOCTL_ISDBT_LONG_WRITE:
  507. err = copy_from_user((void *)&info, (void *)arg, size);
  508. res = BBM_LONG_WRITE(hInit, (u16)info.buff[0]
  509. , (u32)info.buff[1]);
  510. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_LONG_WRITE reg : 0x%x dat : 0x%x\n"
  511. , (u16)info.buff[0], (u32)info.buff[1]);
  512. break;
  513. case IOCTL_ISDBT_BULK_WRITE:
  514. err = copy_from_user((void *)&info, (void *)arg, size);
  515. res = BBM_BULK_WRITE(hInit, (u16)info.buff[0]
  516. , (u8 *)(&info.buff[2]), info.buff[1]);
  517. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_LONG_WRITE reg : 0x%x size : 0x%x\n"
  518. , (u16)info.buff[0], info.buff[1]);
  519. break;
  520. case IOCTL_ISDBT_TUNER_READ:
  521. err = copy_from_user((void *)&info, (void *)arg, size);
  522. res = BBM_TUNER_READ(hInit, (u8)info.buff[0]
  523. , (u8)info.buff[1], (u8 *)(&info.buff[3])
  524. , (u8)info.buff[2]);
  525. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_TUNER_READ reg : 0x%x size : 0x%x\n"
  526. , (u8)info.buff[0], info.buff[3]);
  527. err |= copy_to_user((void *)arg, (void *)&info, size);
  528. break;
  529. case IOCTL_ISDBT_TUNER_WRITE:
  530. err = copy_from_user((void *)&info, (void *)arg, size);
  531. res = BBM_TUNER_WRITE(hInit, (u8)info.buff[0]
  532. , (u8)info.buff[1], (u8 *)(&info.buff[3])
  533. , (u8)info.buff[2]);
  534. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_TUNER_WRITE reg : 0x%x dat : 0x%x\n"
  535. , (u8)info.buff[0], info.buff[3]);
  536. break;
  537. case IOCTL_ISDBT_TUNER_SET_FREQ:
  538. {
  539. u32 f_rf;
  540. err = copy_from_user((void *)&info, (void *)arg, size);
  541. f_rf = ((u32)info.buff[0] - 13) * 6000 + 473143;
  542. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_TUNER_SET_FREQ f_rf : %d chnum : %d\n"
  543. , f_rf, info.buff[0]);
  544. isdbt_isr_check(hInit);
  545. res = BBM_TUNER_SET_FREQ(hInit, f_rf);
  546. mutex_lock(&ringbuffer_lock);
  547. fci_ringbuffer_flush(&hOpen->RingBuffer);
  548. mutex_unlock(&ringbuffer_lock);
  549. BBM_WRITE(hInit, BBM_BUF_INT, 0x01);
  550. }
  551. break;
  552. case IOCTL_ISDBT_TUNER_SELECT:
  553. err = copy_from_user((void *)&info, (void *)arg, size);
  554. res = BBM_TUNER_SELECT(hInit, (u32)info.buff[0], 0);
  555. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_TUNER_SELECT prd : %d\n"
  556. ,info.buff[0]);
  557. break;
  558. case IOCTL_ISDBT_TS_START:
  559. hOpen->isdbttype = TS_TYPE;
  560. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_TS_START\n");
  561. break;
  562. case IOCTL_ISDBT_TS_STOP:
  563. hOpen->isdbttype = 0;
  564. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_TS_STOP\n");
  565. break;
  566. case IOCTL_ISDBT_POWER_ON:
  567. isdbt_hw_init();
  568. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_POWER_ON\n");
  569. break;
  570. case IOCTL_ISDBT_POWER_OFF:
  571. isdbt_hw_deinit();
  572. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_POWER_OFF\n");
  573. break;
  574. case IOCTL_ISDBT_SCAN_STATUS:
  575. res = BBM_SCAN_STATUS(hInit);
  576. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_SCAN_STATUS Lock : %d\n", res);
  577. break;
  578. case IOCTL_ISDBT_TUNER_GET_RSSI:
  579. err = copy_from_user((void *)&info, (void *)arg, size);
  580. res = BBM_TUNER_GET_RSSI(hInit, (s32 *)&info.buff[0]);
  581. PRINTF(hInit, "[FC8150] IOCTL_ISDBT_TUNER_GET_RSSI rssi : %d\n"
  582. , (s32)info.buff[0]);
  583. err |= copy_to_user((void *)arg, (void *)&info, size);
  584. break;
  585. default:
  586. PRINTF(hInit, "isdbt ioctl error!\n");
  587. res = BBM_NOK;
  588. break;
  589. }
  590. if (err < 0) {
  591. PRINTF(hInit, "copy to/from user fail : %d", err);
  592. res = BBM_NOK;
  593. }
  594. return res;
  595. }
  596. #if defined(CONFIG_ISDBT_ANT_DET)
  597. enum {
  598. ISDBT_ANT_OPEN = 0,
  599. ISDBT_ANT_CLOSE,
  600. ISDBT_ANT_UNKNOWN,
  601. };
  602. enum {
  603. ISDBT_ANT_DET_LOW = 0,
  604. ISDBT_ANT_DET_HIGH,
  605. };
  606. static struct input_dev *isdbt_ant_input;
  607. static int isdbt_check_ant;
  608. static int ant_prev_status;
  609. #define ISDBT_ANT_CHECK_DURATION 500000 /* us */
  610. #define ISDBT_ANT_CHECK_COUNT 2
  611. #define ISDBT_ANT_WLOCK_TIMEOUT \
  612. ((ISDBT_ANT_CHECK_DURATION * ISDBT_ANT_CHECK_COUNT * 2) / 1000000)
  613. static int isdbt_ant_det_check_value(void)
  614. {
  615. int loop = 0;
  616. int cur_val = 0, prev_val = 0;
  617. int ret = ISDBT_ANT_UNKNOWN;
  618. isdbt_check_ant = 1;
  619. prev_val = \
  620. ant_prev_status ? ISDBT_ANT_DET_LOW : ISDBT_ANT_DET_HIGH;
  621. for (loop = 0; loop < ISDBT_ANT_CHECK_COUNT; loop++) {
  622. usleep_range(ISDBT_ANT_CHECK_DURATION,\
  623. ISDBT_ANT_CHECK_DURATION);
  624. cur_val = gpio_get_value_cansleep(gpio_cfg.gpio_ant_det);
  625. if (prev_val != cur_val || ant_prev_status == cur_val)
  626. break;
  627. prev_val = cur_val;
  628. }
  629. if (loop == ISDBT_ANT_CHECK_COUNT) {
  630. if (ant_prev_status == ISDBT_ANT_DET_LOW
  631. && cur_val == ISDBT_ANT_DET_HIGH) {
  632. ret = ISDBT_ANT_OPEN;
  633. } else if (ant_prev_status == ISDBT_ANT_DET_HIGH
  634. && cur_val == ISDBT_ANT_DET_LOW) {
  635. ret = ISDBT_ANT_CLOSE;
  636. }
  637. ant_prev_status = cur_val;
  638. }
  639. isdbt_check_ant = 0;
  640. #if 0
  641. printk(KERN_DEBUG "%s cnt(%d) cur(%d) prev(%d)\n",
  642. __func__, loop, cur_val, ant_prev_status);
  643. printk(KERN_DEBUG "system_rev = %d\n", system_rev);
  644. #endif
  645. return ret;
  646. }
  647. static int isdbt_ant_det_ignore_irq(void)
  648. {
  649. /*printk("chk_ant=%d sr=%d\n",
  650. isdbt_check_ant, system_rev); */
  651. return isdbt_check_ant;
  652. }
  653. static void isdbt_ant_det_work_func(struct work_struct *work)
  654. {
  655. if (!isdbt_ant_input) {
  656. printk(KERN_DEBUG \
  657. "%s: input device is not registered\n", __func__);
  658. return;
  659. }
  660. switch (isdbt_ant_det_check_value()) {
  661. case ISDBT_ANT_OPEN:
  662. input_report_key(isdbt_ant_input, KEY_DMB_ANT_DET_UP, 1);
  663. input_report_key(isdbt_ant_input, KEY_DMB_ANT_DET_UP, 0);
  664. input_sync(isdbt_ant_input);
  665. printk(KERN_DEBUG "%s : ISDBT_ANT_OPEN\n", __func__);
  666. break;
  667. case ISDBT_ANT_CLOSE:
  668. input_report_key(isdbt_ant_input, KEY_DMB_ANT_DET_DOWN, 1);
  669. input_report_key(isdbt_ant_input, KEY_DMB_ANT_DET_DOWN, 0);
  670. input_sync(isdbt_ant_input);
  671. printk(KERN_DEBUG "%s : ISDBT_ANT_CLOSE\n", __func__);
  672. break;
  673. case ISDBT_ANT_UNKNOWN:
  674. printk(KERN_DEBUG "%s : ISDBT_ANT_UNKNOWN\n", __func__);
  675. break;
  676. default:
  677. break;
  678. }
  679. }
  680. static struct workqueue_struct *isdbt_ant_det_wq;
  681. static DECLARE_WORK(isdbt_ant_det_work, isdbt_ant_det_work_func);
  682. static bool isdbt_ant_det_reg_input(struct platform_device *pdev)
  683. {
  684. struct input_dev *input;
  685. int err;
  686. printk(KERN_DEBUG "%s\n", __func__);
  687. input = input_allocate_device();
  688. if (!input) {
  689. printk(KERN_DEBUG "Can't allocate input device\n");
  690. err = -ENOMEM;
  691. return false;
  692. }
  693. set_bit(EV_KEY, input->evbit);
  694. set_bit(KEY_DMB_ANT_DET_UP & KEY_MAX, input->keybit);
  695. set_bit(KEY_DMB_ANT_DET_DOWN & KEY_MAX, input->keybit);
  696. input->name = "sec_dmb_key";
  697. input->phys = "sec_dmb_key/input0";
  698. input->dev.parent = &pdev->dev;
  699. err = input_register_device(input);
  700. if (err) {
  701. printk(KERN_DEBUG "Can't register dmb_ant_det key: %d\n", err);
  702. goto free_input_dev;
  703. }
  704. isdbt_ant_input = input;
  705. ant_prev_status = gpio_get_value_cansleep(gpio_cfg.gpio_ant_det);
  706. return true;
  707. free_input_dev:
  708. input_free_device(input);
  709. return false;
  710. }
  711. static void isdbt_ant_det_unreg_input(void)
  712. {
  713. input_unregister_device(isdbt_ant_input);
  714. }
  715. static bool isdbt_ant_det_create_wq(void)
  716. {
  717. printk(KERN_DEBUG "%s\n", __func__);
  718. isdbt_ant_det_wq = create_singlethread_workqueue("isdbt_ant_det_wq");
  719. if (isdbt_ant_det_wq)
  720. return true;
  721. else
  722. return false;
  723. }
  724. static bool isdbt_ant_det_destroy_wq(void)
  725. {
  726. if (isdbt_ant_det_wq) {
  727. flush_workqueue(isdbt_ant_det_wq);
  728. destroy_workqueue(isdbt_ant_det_wq);
  729. isdbt_ant_det_wq = NULL;
  730. }
  731. return true;
  732. }
  733. static irqreturn_t isdbt_ant_det_irq_handler(int irq, void *dev_id)
  734. {
  735. int ret = 0;
  736. if (isdbt_ant_det_ignore_irq())
  737. return IRQ_HANDLED;
  738. wake_lock_timeout(&isdbt_ant_wlock, ISDBT_ANT_WLOCK_TIMEOUT * HZ);
  739. if (isdbt_ant_det_wq) {
  740. ret = queue_work(isdbt_ant_det_wq, &isdbt_ant_det_work);
  741. if (ret == 0)
  742. printk(KERN_DEBUG "%s queue_work fail\n", __func__);
  743. }
  744. return IRQ_HANDLED;
  745. }
  746. static bool isdbt_ant_det_irq_set(bool set)
  747. {
  748. bool ret = true;
  749. int irq_ret;
  750. if (set) {
  751. irq_set_irq_type(gpio_cfg.irq_ant_det, IRQ_TYPE_EDGE_BOTH);
  752. irq_ret = request_irq(gpio_cfg.irq_ant_det
  753. , isdbt_ant_det_irq_handler
  754. , IRQF_DISABLED
  755. , "isdbt_ant_det"
  756. , NULL);
  757. if (irq_ret < 0) {
  758. printk(KERN_DEBUG "%s %d\r\n", __func__, irq_ret);
  759. ret = false;
  760. }
  761. enable_irq_wake(gpio_cfg.irq_ant_det);
  762. } else {
  763. disable_irq_wake(gpio_cfg.irq_ant_det);
  764. free_irq(gpio_cfg.irq_ant_det, NULL);
  765. }
  766. return ret;
  767. }
  768. #endif
  769. static int isdbt_probe(struct platform_device *pdev)
  770. {
  771. int res;
  772. struct isdbt_platform_data *p = pdev->dev.platform_data;
  773. memcpy(&gpio_cfg, p, sizeof(struct isdbt_platform_data));
  774. res = misc_register(&fc8150_misc_device);
  775. if (res < 0) {
  776. PRINTF(hInit, "isdbt init fail : %d\n", res);
  777. return res;
  778. }
  779. isdbt_hw_setting();
  780. // isdbt_hw_init(); //hs.yi@latinsw1system ISDBT_PWR_EN pin unstable for bootup
  781. hInit = kmalloc(sizeof(struct ISDBT_INIT_INFO_T), GFP_KERNEL);
  782. res = BBM_HOSTIF_SELECT(hInit, BBM_SPI);
  783. if (res)
  784. PRINTF(hInit, "isdbt host interface select fail!\n");
  785. // isdbt_hw_deinit(); //hs.yi@latinsw1system ISDBT_PWR_EN pin unstable for bootup
  786. if (!isdbt_kthread) {
  787. PRINTF(hInit, "kthread run\n");
  788. isdbt_kthread = kthread_run(isdbt_thread
  789. , (void *)hInit, "isdbt_thread");
  790. }
  791. INIT_LIST_HEAD(&(hInit->hHead));
  792. #if defined(CONFIG_ISDBT_ANT_DET)
  793. wake_lock_init(&isdbt_ant_wlock, WAKE_LOCK_SUSPEND, "isdbt_ant_wlock");
  794. if (!isdbt_ant_det_reg_input(pdev))
  795. goto err_reg_input;
  796. if (!isdbt_ant_det_create_wq())
  797. goto free_reg_input;
  798. if (!isdbt_ant_det_irq_set(true))
  799. goto free_ant_det_wq;
  800. return 0;
  801. free_ant_det_wq:
  802. isdbt_ant_det_destroy_wq();
  803. free_reg_input:
  804. isdbt_ant_det_unreg_input();
  805. err_reg_input:
  806. return -EFAULT;
  807. #else
  808. return 0;
  809. #endif
  810. }
  811. static int isdbt_remove(struct platform_device *pdev)
  812. {
  813. printk(KERN_DEBUG "ISDBT remove\n");
  814. #if defined(CONFIG_ISDBT_ANT_DET)
  815. isdbt_ant_det_unreg_input();
  816. isdbt_ant_det_destroy_wq();
  817. isdbt_ant_det_irq_set(false);
  818. wake_lock_destroy(&isdbt_ant_wlock);
  819. #endif
  820. return 0;
  821. }
  822. static int isdbt_suspend(struct platform_device *pdev, pm_message_t mesg)
  823. {
  824. return 0;
  825. }
  826. static int isdbt_resume(struct platform_device *pdev)
  827. {
  828. return 0;
  829. }
  830. void isdbt_exit(void);
  831. static int isdbt_shutdown(struct platform_device *pdev)
  832. {
  833. isdbt_exit();
  834. return 0;
  835. }
  836. static struct platform_driver isdbt_driver = {
  837. .probe = isdbt_probe,
  838. .remove = isdbt_remove,
  839. .suspend = isdbt_suspend,
  840. .resume = isdbt_resume,
  841. .shutdown = isdbt_shutdown,
  842. .driver = {
  843. .owner = THIS_MODULE,
  844. .name = "isdbt"
  845. },
  846. };
  847. int isdbt_init(void)
  848. {
  849. s32 res;
  850. PRINTF(hInit, "isdbt_init\n");
  851. res = platform_driver_register(&isdbt_driver);
  852. if (res < 0) {
  853. PRINTF(hInit, "isdbt init fail : %d\n", res);
  854. return res;
  855. }
  856. return 0;
  857. }
  858. void isdbt_exit(void)
  859. {
  860. PRINTF(hInit, "isdbt isdbt_exit\n");
  861. isdbt_hw_deinit();
  862. free_irq(gpio_to_irq(GPIO_ISDBT_IRQ_FC8150), NULL);
  863. gpio_free(GPIO_ISDBT_IRQ_FC8150);
  864. gpio_free(GPIO_ISDBT_RST_FC8150);
  865. gpio_free(GPIO_ISDBT_PWR_EN_FC8150);
  866. kthread_stop(isdbt_kthread);
  867. isdbt_kthread = NULL;
  868. BBM_HOSTIF_DESELECT(hInit);
  869. isdbt_hw_deinit();
  870. platform_driver_unregister(&isdbt_driver);
  871. misc_deregister(&fc8150_misc_device);
  872. kfree(hInit);
  873. }
  874. module_init(isdbt_init);
  875. module_exit(isdbt_exit);
  876. MODULE_LICENSE("Dual BSD/GPL");