fc8300.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157
  1. /*****************************************************************************
  2. Copyright(c) 2013 FCI Inc. All Rights Reserved
  3. File name : fc8300.c
  4. Description : Driver source file
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. History :
  17. ----------------------------------------------------------------------
  18. *******************************************************************************/
  19. #include <linux/miscdevice.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/kthread.h>
  22. #include <linux/poll.h>
  23. #include <linux/vmalloc.h>
  24. #include <linux/irq.h>
  25. #include <linux/delay.h>
  26. #include <linux/slab.h>
  27. #include <linux/gpio.h>
  28. #include <linux/module.h>
  29. #include <linux/io.h>
  30. #include <mach/isdbt_tuner_pdata.h>
  31. #include <mach/sec_debug.h>
  32. #include <mach/gpio.h>
  33. #include <linux/platform_device.h>
  34. #include <linux/wakelock.h>
  35. #include <linux/input.h>
  36. #include <mach/gpiomux.h>
  37. #include <linux/of_gpio.h>
  38. #include "fc8300.h"
  39. #include "fc8300_i2c.h"
  40. #include "bbm.h"
  41. #include "fci_oal.h"
  42. #include "fci_tun.h"
  43. #include "fc8300_regs.h"
  44. #include "fc8300_isr.h"
  45. #include "fci_hal.h"
  46. #include <asm/system_info.h>
  47. struct ISDBT_INIT_INFO_T *hInit;
  48. #define RING_BUFFER_SIZE (188 * 320 * 17)
  49. /* GPIO(RESET & INTRRUPT) Setting */
  50. #define FC8300_NAME "isdbt"
  51. static struct isdbt_platform_data *isdbt_pdata;
  52. #define TS0_1SEG_LENGTH (188 * 32)
  53. #define TS0_TMM_13SEG_LENGTH (188 * 96)
  54. u8 static_ringbuffer[RING_BUFFER_SIZE];
  55. #ifdef TS_DROP_DEBUG
  56. #define FEATURE_TS_CHECK
  57. #ifdef FEATURE_TS_CHECK
  58. u32 check_cnt_size;
  59. #define MAX_DEMUX 2
  60. /*
  61. * Sync Byte 0xb8
  62. */
  63. #define SYNC_BYTE_INVERSION
  64. struct pid_info {
  65. unsigned long count;
  66. unsigned long discontinuity;
  67. unsigned long continuity;
  68. };
  69. struct demux_info {
  70. struct pid_info pids[8192];
  71. unsigned long ts_packet_c;
  72. unsigned long malformed_packet_c;
  73. unsigned long tot_scraped_sz;
  74. unsigned long packet_no;
  75. unsigned long sync_err;
  76. unsigned long sync_err_set;
  77. };
  78. static int is_sync(unsigned char *p)
  79. {
  80. int syncword = p[0];
  81. #ifdef SYNC_BYTE_INVERSION
  82. if (0x47 == syncword || 0xb8 == syncword)
  83. return 1;
  84. #else
  85. if (0x47 == syncword)
  86. return 1;
  87. #endif
  88. return 0;
  89. }
  90. static struct demux_info demux[MAX_DEMUX];
  91. int print_pkt_log(void)
  92. {
  93. unsigned long i = 0;
  94. print_log(NULL, "\nPKT_TOT : %d, SYNC_ERR : %d, SYNC_ERR_BIT : %d \
  95. , ERR_PKT : %d \n"
  96. , demux[0].ts_packet_c, demux[0].sync_err
  97. , demux[0].sync_err_set, demux[0].malformed_packet_c);
  98. for (i = 0; i < 8192; i++) {
  99. if (demux[0].pids[i].count > 0)
  100. print_log(NULL, "PID : %d, TOT_PKT : %d\
  101. , DISCONTINUITY : %d \n"
  102. , i, demux[0].pids[i].count
  103. , demux[0].pids[i].discontinuity);
  104. }
  105. return 0;
  106. }
  107. int put_ts_packet(int no, unsigned char *packet, int sz)
  108. {
  109. unsigned char *p;
  110. int transport_error_indicator, pid, payload_unit_start_indicator;
  111. int continuity_counter, last_continuity_counter;
  112. int i;
  113. if ((sz % 188)) {
  114. print_log(NULL, "L : %d", sz);
  115. } else {
  116. for (i = 0; i < sz; i += 188) {
  117. p = packet + i;
  118. pid = ((p[1] & 0x1f) << 8) + p[2];
  119. demux[no].ts_packet_c++;
  120. if (!is_sync(packet + i)) {
  121. print_log(NULL, "S ");
  122. demux[no].sync_err++;
  123. if (0x80 == (p[1] & 0x80))
  124. demux[no].sync_err_set++;
  125. print_log(NULL, "0x%x, 0x%x, 0x%x, 0x%x \n"
  126. , *p, *(p+1), *(p+2), *(p+3));
  127. continue;
  128. }
  129. transport_error_indicator = (p[1] & 0x80) >> 7;
  130. if (1 == transport_error_indicator) {
  131. demux[no].malformed_packet_c++;
  132. continue;
  133. }
  134. payload_unit_start_indicator = (p[1] & 0x40) >> 6;
  135. demux[no].pids[pid].count++;
  136. continuity_counter = p[3] & 0x0f;
  137. if (demux[no].pids[pid].continuity == -1) {
  138. demux[no].pids[pid].continuity
  139. = continuity_counter;
  140. } else {
  141. last_continuity_counter
  142. = demux[no].pids[pid].continuity;
  143. demux[no].pids[pid].continuity
  144. = continuity_counter;
  145. if (((last_continuity_counter + 1) & 0x0f)
  146. != continuity_counter) {
  147. demux[no].pids[pid].discontinuity++;
  148. }
  149. }
  150. }
  151. }
  152. return 0;
  153. }
  154. void create_tspacket_anal(void)
  155. {
  156. int n, i;
  157. for (n = 0; n < MAX_DEMUX; n++) {
  158. memset((void *)&demux[n], 0, sizeof(demux[n]));
  159. for (i = 0; i < 8192; i++)
  160. demux[n].pids[i].continuity = -1;
  161. }
  162. }
  163. #endif
  164. #endif
  165. enum ISDBT_MODE driver_mode = ISDBT_POWEROFF;
  166. static DEFINE_MUTEX(ringbuffer_lock);
  167. static DECLARE_WAIT_QUEUE_HEAD(isdbt_isr_wait);
  168. static long open_cnt = 0; /* OPEN counter */
  169. static long moni_cnt = 0; /* Monitor counter */
  170. #ifndef BBM_I2C_TSIF
  171. static u8 isdbt_isr_sig;
  172. static struct task_struct *isdbt_kthread;
  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. #endif
  180. static int tuner_ioctl_set_monitor_mode ( struct file* FIle,
  181. unsigned int cmd,
  182. unsigned long arg )
  183. {
  184. int ret = 0;
  185. ISDB_PR_DBG("tuner_ioctl_set_monitor_mode << Start >> ");
  186. if ( 1 == arg )
  187. {
  188. /* Monitor Mode Start */
  189. moni_cnt++;
  190. }
  191. else
  192. {
  193. /* Monitor Mode Stop */
  194. moni_cnt--;
  195. if ( 0 > moni_cnt )
  196. {
  197. ISDB_PR_INFO(" tuner_ioctl_set_monitor_mode under counter = %ld => 0", moni_cnt );
  198. moni_cnt = 0;
  199. }
  200. }
  201. ISDB_PR_INFO("tuner_ioctl_set_monitor_mode << End >> : moni_cnt = %ld",
  202. moni_cnt );
  203. return ( ret );
  204. }
  205. static int tuner_ioctl_get_open_count ( struct file* FIle,
  206. unsigned int cmd,
  207. unsigned long arg )
  208. {
  209. TUNER_STS_DATA *arg_data;
  210. int ret = 0;
  211. unsigned long temp_open = 0,
  212. temp_moni = 0;
  213. ISDB_PR_INFO("tuner_ioctl_get_open_count << Start >> : open = %ld",
  214. ( open_cnt - moni_cnt ));
  215. /* Parameter check */
  216. arg_data = (TUNER_STS_DATA*)arg;
  217. if ( NULL == arg_data )
  218. {
  219. ISDB_PR_ERR("Parameter Error : arg = NULL");
  220. return ( -1 );
  221. }
  222. /* state check */
  223. if ( open_cnt < moni_cnt )
  224. {
  225. ISDB_PR_ERR("tuner_ioctl_get_open_count Error : open = %ld, moni = %ld",
  226. open_cnt, moni_cnt );
  227. return ( -1 );
  228. }
  229. temp_open = (open_cnt - moni_cnt);
  230. temp_moni = moni_cnt;
  231. /* Copy to User Area */
  232. ret = put_user ( temp_open, (unsigned long __user *)&(arg_data->open_cnt) );
  233. if ( 0 != ret )
  234. {
  235. ISDB_PR_ERR("tuner_ioctl_get_open_count put_user(arg_data->open_cnt) Error : ret = %d", ret );
  236. return ( -1 );
  237. }
  238. /* Copy to User Area */
  239. ret = put_user ( moni_cnt, (unsigned long __user *)&(arg_data->moni_cnt) );
  240. if ( 0 != ret )
  241. {
  242. ISDB_PR_ERR("tuner_ioctl_get_open_count put_user(arg_data->moni_cnt) Error : ret = %d", ret );
  243. return ( -1 );
  244. }
  245. ISDB_PR_DBG("tuner_ioctl_get_open_count << End >>");
  246. ISDB_PR_INFO(" Open Count Result : %ld", open_cnt );
  247. ISDB_PR_INFO(" Monitor Count Result : %ld", moni_cnt );
  248. return ( 0 );
  249. }
  250. int isdbt_hw_setting(void)
  251. {
  252. int err;
  253. ISDB_PR_INFO("isdbt_hw_setting \n");
  254. err = gpio_request(isdbt_pdata->gpio_en, "isdbt_en");
  255. if (err) {
  256. ISDB_PR_ERR("isdbt_hw_setting: Couldn't request isdbt_en\n");
  257. goto ISBT_EN_ERR;
  258. }
  259. gpio_direction_output(isdbt_pdata->gpio_en, 0);
  260. err = gpio_request(isdbt_pdata->gpio_rst, "isdbt_rst");
  261. if (err) {
  262. ISDB_PR_ERR("isdbt_hw_setting: Couldn't request isdbt_rst\n");
  263. goto ISDBT_RST_ERR;
  264. }
  265. gpio_direction_output(isdbt_pdata->gpio_rst, 0);
  266. #ifndef BBM_I2C_TSIF
  267. err = gpio_request(isdbt_pdata->gpio_int, "isdbt_irq");
  268. if (err) {
  269. ISDB_PR_ERR("isdbt_hw_setting: Couldn't request isdbt_irq\n");
  270. goto ISDBT_INT_ERR;
  271. }
  272. gpio_direction_input(isdbt_pdata->gpio_int);
  273. err = request_irq(gpio_to_irq(isdbt_pdata->gpio_int), isdbt_irq
  274. , IRQF_DISABLED | IRQF_TRIGGER_FALLING, FC8300_NAME, NULL);
  275. if (err < 0) {
  276. ISDB_PR_ERR("isdbt_hw_setting: couldn't request gpio \
  277. interrupt %d reason(%d)\n"
  278. , gpio_to_irq(isdbt_pdata->gpio_int), err);
  279. goto request_isdbt_irq;
  280. }
  281. #endif
  282. return 0;
  283. #ifndef BBM_I2C_TSIF
  284. request_isdbt_irq:
  285. gpio_free(isdbt_pdata->gpio_int);
  286. ISDBT_INT_ERR:
  287. gpio_free(isdbt_pdata->gpio_rst);
  288. #endif
  289. ISDBT_RST_ERR:
  290. gpio_free(isdbt_pdata->gpio_en);
  291. ISBT_EN_ERR:
  292. return err;
  293. }
  294. static void isdbt_gpio_init(void)
  295. {
  296. ISDB_PR_INFO("%s\n",__func__);
  297. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_en, GPIOMUX_FUNC_GPIO,
  298. GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
  299. GPIO_CFG_ENABLE);
  300. //gpio_set_value(isdbt_pdata->gpio_en, 0);
  301. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_rst, GPIOMUX_FUNC_GPIO,
  302. GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
  303. GPIO_CFG_ENABLE);
  304. //gpio_set_value(isdbt_pdata->gpio_rst, 0);
  305. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_int, GPIOMUX_FUNC_GPIO,
  306. GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
  307. GPIO_CFG_ENABLE);
  308. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_i2c_sda, GPIOMUX_FUNC_3,
  309. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
  310. GPIO_CFG_ENABLE);
  311. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_i2c_scl, GPIOMUX_FUNC_3,
  312. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
  313. GPIO_CFG_ENABLE);
  314. /*
  315. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_spi_di, GPIOMUX_FUNC_2,
  316. GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
  317. GPIO_CFG_ENABLE);
  318. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_spi_do, GPIOMUX_FUNC_2,
  319. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
  320. GPIO_CFG_ENABLE);
  321. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_spi_cs, GPIOMUX_FUNC_2,
  322. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
  323. GPIO_CFG_ENABLE);
  324. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_spi_clk, GPIOMUX_FUNC_2,
  325. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
  326. GPIO_CFG_ENABLE);
  327. */
  328. isdbt_hw_setting();
  329. }
  330. /*POWER_ON & HW_RESET & INTERRUPT_CLEAR */
  331. void isdbt_hw_init(void)
  332. {
  333. int i = 0;
  334. while (driver_mode == ISDBT_DATAREAD) {
  335. msWait(100);
  336. if (i++ > 5)
  337. break;
  338. }
  339. ISDB_PR_INFO("isdbt_hw_init \n");
  340. gpio_set_value(isdbt_pdata->gpio_rst, 0);
  341. gpio_set_value(isdbt_pdata->gpio_en, 1);
  342. mdelay(5);
  343. gpio_set_value(isdbt_pdata->gpio_rst, 1);
  344. mdelay(5);
  345. driver_mode = ISDBT_POWERON;
  346. }
  347. /*POWER_OFF */
  348. void isdbt_hw_deinit(void)
  349. {
  350. ISDB_PR_INFO("isdbt_hw_deinit \n");
  351. driver_mode = ISDBT_POWEROFF;
  352. gpio_set_value(isdbt_pdata->gpio_en, 0);
  353. gpio_set_value(isdbt_pdata->gpio_rst, 0);
  354. }
  355. int data_callback(u32 hDevice, u8 bufid, u8 *data, int len)
  356. {
  357. struct ISDBT_INIT_INFO_T *hInit;
  358. struct list_head *temp;
  359. hInit = (struct ISDBT_INIT_INFO_T *)hDevice;
  360. list_for_each(temp, &(hInit->hHead))
  361. {
  362. struct ISDBT_OPEN_INFO_T *hOpen;
  363. hOpen = list_entry(temp, struct ISDBT_OPEN_INFO_T, hList);
  364. if (hOpen->isdbttype == TS_TYPE) {
  365. #ifdef TS_DROP_DEBUG
  366. #if 0//def FEATURE_TS_CHECK
  367. if (!(len%188)) {
  368. put_ts_packet(0, data, len);
  369. check_cnt_size += len;
  370. if (check_cnt_size > 188*32*200) {
  371. print_pkt_log();
  372. check_cnt_size = 0;
  373. }
  374. }
  375. #endif
  376. #endif
  377. mutex_lock(&ringbuffer_lock);
  378. if (fci_ringbuffer_free(&hOpen->RingBuffer) < len) {
  379. #ifdef TS_DROP_DEBUG
  380. print_log(NULL, "[FC8300] RingBuffer full \n");
  381. #endif
  382. /* return 0 */;
  383. FCI_RINGBUFFER_SKIP(&hOpen->RingBuffer, len);
  384. }
  385. #ifdef TS_DROP_DEBUG
  386. print_log(NULL, "[FC8300] RingBuffer Write %d \n", len);
  387. #endif
  388. fci_ringbuffer_write(&hOpen->RingBuffer, data, len);
  389. ISDB_PR_DBG("data_callback : %d [0x%x][0x%x]\n", len, data[0], data[1]);
  390. wake_up_interruptible(&(hOpen->RingBuffer.queue));
  391. mutex_unlock(&ringbuffer_lock);
  392. }
  393. #ifdef TS_DROP_DEBUG
  394. else
  395. print_log(NULL, "[FC8300] Data callback : TS Stop \n");
  396. #endif
  397. }
  398. return 0;
  399. }
  400. #ifndef BBM_I2C_TSIF
  401. static int isdbt_thread(void *hDevice)
  402. {
  403. struct ISDBT_INIT_INFO_T *hInit = (struct ISDBT_INIT_INFO_T *)hDevice;
  404. set_user_nice(current, -20);
  405. ISDB_PR_INFO("isdbt_kthread enter\n");
  406. bbm_com_ts_callback_register((u32)hInit, data_callback);
  407. while (1) {
  408. wait_event_interruptible(isdbt_isr_wait,
  409. isdbt_isr_sig || kthread_should_stop());
  410. if (driver_mode == ISDBT_POWERON) {
  411. driver_mode = ISDBT_DATAREAD;
  412. bbm_com_isr(hInit);
  413. driver_mode = ISDBT_POWERON;
  414. }
  415. isdbt_isr_sig = 0;
  416. if (kthread_should_stop())
  417. break;
  418. }
  419. bbm_com_ts_callback_deregister();
  420. ISDB_PR_INFO("isdbt_kthread exit\n");
  421. return 0;
  422. }
  423. #endif
  424. const struct file_operations isdbt_fops = {
  425. .owner = THIS_MODULE,
  426. .unlocked_ioctl = isdbt_ioctl,
  427. .open = isdbt_open,
  428. .read = isdbt_read,
  429. .release = isdbt_release,
  430. };
  431. static struct miscdevice fc8300_misc_device = {
  432. .minor = MISC_DYNAMIC_MINOR,
  433. .name = FC8300_NAME,
  434. .fops = &isdbt_fops,
  435. };
  436. int isdbt_open(struct inode *inode, struct file *filp)
  437. {
  438. struct ISDBT_OPEN_INFO_T *hOpen;
  439. ISDB_PR_INFO("isdbt open\n");
  440. open_cnt++;
  441. hOpen = kmalloc(sizeof(struct ISDBT_OPEN_INFO_T), GFP_KERNEL);
  442. hOpen->buf = &static_ringbuffer[0];
  443. /*kmalloc(RING_BUFFER_SIZE, GFP_KERNEL);*/
  444. hOpen->isdbttype = 0;
  445. list_add(&(hOpen->hList), &(hInit->hHead));
  446. hOpen->hInit = (HANDLE *)hInit;
  447. if (hOpen->buf == NULL) {
  448. ISDB_PR_ERR("ring buffer malloc error\n");
  449. return -ENOMEM;
  450. }
  451. fci_ringbuffer_init(&hOpen->RingBuffer, hOpen->buf, RING_BUFFER_SIZE);
  452. filp->private_data = hOpen;
  453. return 0;
  454. }
  455. ssize_t isdbt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
  456. {
  457. s32 avail;
  458. s32 non_blocking = filp->f_flags & O_NONBLOCK;
  459. struct ISDBT_OPEN_INFO_T *hOpen
  460. = (struct ISDBT_OPEN_INFO_T *)filp->private_data;
  461. struct fci_ringbuffer *cibuf = &hOpen->RingBuffer;
  462. ssize_t len, read_len = 0;
  463. if (!cibuf->data || !count) {
  464. ISDB_PR_INFO(" return 0\n");
  465. return 0;
  466. }
  467. if (non_blocking && (fci_ringbuffer_empty(cibuf))) {
  468. return -EWOULDBLOCK;
  469. }
  470. if (wait_event_interruptible(cibuf->queue,
  471. !fci_ringbuffer_empty(cibuf))) {
  472. ISDB_PR_INFO("return ERESTARTSYS\n");
  473. return -ERESTARTSYS;
  474. }
  475. mutex_lock(&ringbuffer_lock);
  476. avail = fci_ringbuffer_avail(cibuf);
  477. if (count >= avail)
  478. len = avail;
  479. else
  480. len = count - (count % 188);
  481. read_len = fci_ringbuffer_read_user(cibuf, buf, len);
  482. #ifdef TS_DROP_DEBUG
  483. #ifdef FEATURE_TS_CHECK
  484. if (!(read_len%188)) {
  485. put_ts_packet(0, buf, read_len);
  486. check_cnt_size += read_len;
  487. if (check_cnt_size > 188*32*200) {
  488. print_pkt_log();
  489. check_cnt_size = 0;
  490. }
  491. }
  492. else
  493. print_log(NULL, "[FC8300] Read Len Error %d \n", read_len);
  494. #endif
  495. #endif
  496. mutex_unlock(&ringbuffer_lock);
  497. #ifdef TS_DROP_DEBUG
  498. print_log(hInit, "[FC8300] RingBuffer Read %d Buffer : %d\n", read_len, count);
  499. #endif
  500. return read_len;
  501. }
  502. int isdbt_release(struct inode *inode, struct file *filp)
  503. {
  504. struct ISDBT_OPEN_INFO_T *hOpen;
  505. ISDB_PR_INFO("isdbt_release\n");
  506. if( open_cnt <= 0 )
  507. {
  508. printk("tuner_module_entry_close: close error\n");
  509. open_cnt = 0;
  510. return -1;
  511. }
  512. else
  513. {
  514. open_cnt--;
  515. }
  516. /* close all open */
  517. if( open_cnt == 0 )
  518. {
  519. hOpen = filp->private_data;
  520. //prevent issue CID 27514
  521. if (hOpen != NULL)
  522. {
  523. hOpen->isdbttype = 0;
  524. list_del(&(hOpen->hList));
  525. ISDB_PR_INFO("isdbt_release hList\n");
  526. /*kfree(hOpen->buf);*/
  527. kfree(hOpen);
  528. }
  529. }
  530. return 0;
  531. }
  532. #ifndef BBM_I2C_TSIF
  533. void isdbt_isr_check(HANDLE hDevice)
  534. {
  535. u8 isr_time = 0;
  536. bbm_com_write(hDevice, DIV_BROADCAST, BBM_BUF_INT_ENABLE, 0x00);
  537. while (isr_time < 10) {
  538. if (!isdbt_isr_sig)
  539. break;
  540. msWait(10);
  541. isr_time++;
  542. }
  543. }
  544. #endif
  545. long isdbt_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  546. {
  547. s32 res = BBM_NOK;
  548. s32 err = 0;
  549. s32 size = 0;
  550. struct ISDBT_OPEN_INFO_T *hOpen;
  551. struct ioctl_info info;
  552. if (_IOC_TYPE(cmd) != IOCTL_MAGIC)
  553. return -EINVAL;
  554. if (_IOC_NR(cmd) >= IOCTL_MAXNR)
  555. return -EINVAL;
  556. hOpen = filp->private_data;
  557. size = _IOC_SIZE(cmd);
  558. switch (cmd) {
  559. case IOCTL_ISDBT_RESET:
  560. res = bbm_com_reset(hInit, DIV_BROADCAST);
  561. ISDB_PR_INFO("IOCTL_ISDBT_RESET \n");
  562. break;
  563. case IOCTL_ISDBT_INIT:
  564. ISDB_PR_DBG("IOCTL_ISDBT_INIT \n");
  565. res = bbm_com_i2c_init(hInit, FCI_HPI_TYPE);
  566. ISDB_PR_INFO("IOCTL_ISDBT_INIT bbm_com_i2c_init res =%d \n",res);
  567. res |= bbm_com_probe(hInit, DIV_BROADCAST);
  568. if (res) {
  569. ISDB_PR_ERR("FC8300 Initialize Fail \n");
  570. break;
  571. }
  572. ISDB_PR_DBG("IOCTL_ISDBT_INIT bbm_com_probe success \n");
  573. res |= bbm_com_init(hInit, DIV_BROADCAST);
  574. ISDB_PR_DBG("IOCTL_ISDBT_INITbbm_com_init \n");
  575. #if 0
  576. res |= bbm_com_tuner_select(hInit
  577. , DIV_BROADCAST, FC8300_TUNER, ISDBT_13SEG);
  578. #endif
  579. break;
  580. case IOCTL_ISDBT_BYTE_READ:
  581. ISDB_PR_INFO("IOCTL_ISDBT_BYTE_READ \n");
  582. err = copy_from_user((void *)&info, (void *)arg, size);
  583. res = bbm_com_byte_read(hInit, DIV_BROADCAST, (u16)info.buff[0]
  584. , (u8 *)(&info.buff[1]));
  585. err |= copy_to_user((void *)arg, (void *)&info, size);
  586. break;
  587. case IOCTL_ISDBT_WORD_READ:
  588. err = copy_from_user((void *)&info, (void *)arg, size);
  589. res = bbm_com_word_read(hInit, DIV_BROADCAST, (u16)info.buff[0]
  590. , (u16 *)(&info.buff[1]));
  591. err |= copy_to_user((void *)arg, (void *)&info, size);
  592. break;
  593. case IOCTL_ISDBT_LONG_READ:
  594. err = copy_from_user((void *)&info, (void *)arg, size);
  595. res = bbm_com_long_read(hInit, DIV_BROADCAST, (u16)info.buff[0]
  596. , (u32 *)(&info.buff[1]));
  597. err |= copy_to_user((void *)arg, (void *)&info, size);
  598. break;
  599. case IOCTL_ISDBT_BULK_READ:
  600. err = copy_from_user((void *)&info, (void *)arg, size);
  601. res = bbm_com_bulk_read(hInit, DIV_BROADCAST, (u16)info.buff[0]
  602. , (u8 *)(&info.buff[2]), info.buff[1]);
  603. err |= copy_to_user((void *)arg, (void *)&info, size);
  604. break;
  605. case IOCTL_ISDBT_BYTE_WRITE:
  606. err = copy_from_user((void *)&info, (void *)arg, size);
  607. res = bbm_com_byte_write(hInit, DIV_BROADCAST, (u16)info.buff[0]
  608. , (u8)info.buff[1]);
  609. break;
  610. case IOCTL_ISDBT_WORD_WRITE:
  611. err = copy_from_user((void *)&info, (void *)arg, size);
  612. res = bbm_com_word_write(hInit, DIV_BROADCAST, (u16)info.buff[0]
  613. , (u16)info.buff[1]);
  614. break;
  615. case IOCTL_ISDBT_LONG_WRITE:
  616. err = copy_from_user((void *)&info, (void *)arg, size);
  617. res = bbm_com_long_write(hInit, DIV_BROADCAST, (u16)info.buff[0]
  618. , (u32)info.buff[1]);
  619. break;
  620. case IOCTL_ISDBT_BULK_WRITE:
  621. err = copy_from_user((void *)&info, (void *)arg, size);
  622. res = bbm_com_bulk_write(hInit, DIV_BROADCAST, (u16)info.buff[0]
  623. , (u8 *)(&info.buff[2]), info.buff[1]);
  624. break;
  625. case IOCTL_ISDBT_TUNER_READ:
  626. err = copy_from_user((void *)&info, (void *)arg, size);
  627. res = bbm_com_tuner_read(hInit, DIV_BROADCAST, (u8)info.buff[0]
  628. , (u8)info.buff[1], (u8 *)(&info.buff[3])
  629. , (u8)info.buff[2]);
  630. err |= copy_to_user((void *)arg, (void *)&info, size);
  631. break;
  632. case IOCTL_ISDBT_TUNER_WRITE:
  633. err = copy_from_user((void *)&info, (void *)arg, size);
  634. res = bbm_com_tuner_write(hInit, DIV_BROADCAST, (u8)info.buff[0]
  635. , (u8)info.buff[1], (u8 *)(&info.buff[3])
  636. , (u8)info.buff[2]);
  637. break;
  638. case IOCTL_ISDBT_TUNER_SET_FREQ:
  639. {
  640. u32 f_rf;
  641. u8 subch;
  642. err = copy_from_user((void *)&info, (void *)arg, size);
  643. f_rf = (u32)info.buff[0];
  644. subch = (u8)info.buff[1];
  645. ISDB_PR_DBG("IOCTL_ISDBT_TUNER_SET_FREQ \
  646. : f_rf[%d], subch[%d]\n", f_rf, subch);
  647. #ifndef BBM_I2C_TSIF
  648. isdbt_isr_check(hInit);
  649. #endif
  650. res = bbm_com_tuner_set_freq(hInit
  651. , DIV_BROADCAST, f_rf, subch);
  652. #ifndef BBM_I2C_TSIF
  653. mutex_lock(&ringbuffer_lock);
  654. fci_ringbuffer_flush(&hOpen->RingBuffer);
  655. mutex_unlock(&ringbuffer_lock);
  656. bbm_com_write(hInit
  657. , DIV_BROADCAST, BBM_BUF_INT_ENABLE, 0x01);
  658. #endif
  659. ISDB_PR_DBG("IOCTL_ISDBT_TUNER_SET_FREQ BUF En\n");
  660. }
  661. break;
  662. case IOCTL_ISDBT_TUNER_SELECT:
  663. ISDB_PR_INFO("IOCTL_ISDBT_TUNER_SELECT \n");
  664. err = copy_from_user((void *)&info, (void *)arg, size);
  665. res = bbm_com_tuner_select(hInit
  666. , DIV_BROADCAST, (u32)info.buff[0], (u32)info.buff[1]);
  667. if (((u32)info.buff[1] != ISDBT_13SEG)
  668. && ((u32)info.buff[1] != ISDBTMM_13SEG)) {
  669. bbm_com_word_write(hInit, DIV_BROADCAST, BBM_BUF_TS0_START, 0);
  670. bbm_com_word_write(hInit, DIV_BROADCAST, BBM_BUF_TS0_END
  671. , TS0_1SEG_LENGTH - 1);
  672. bbm_com_word_write(hInit, DIV_BROADCAST, BBM_BUF_TS0_THR
  673. , TS0_1SEG_LENGTH / 2 - 1);
  674. ISDB_PR_DBG("TUNER THRESHOLD: %d \n"
  675. , TS0_1SEG_LENGTH / 2 - 1);
  676. } else if ((u32)info.buff[1] == ISDBTMM_13SEG) {
  677. bbm_com_word_write(hInit, DIV_BROADCAST, BBM_BUF_TS0_START, 0);
  678. bbm_com_word_write(hInit, DIV_BROADCAST, BBM_BUF_TS0_END
  679. , TS0_TMM_13SEG_LENGTH - 1);
  680. bbm_com_word_write(hInit, DIV_BROADCAST, BBM_BUF_TS0_THR
  681. , TS0_TMM_13SEG_LENGTH / 2 - 1);
  682. ISDB_PR_DBG("TUNER THRESHOLD: %d \n"
  683. , TS0_TMM_13SEG_LENGTH / 2 - 1);
  684. }
  685. ISDB_PR_DBG("IOCTL_ISDBT_TUNER_SELECT %d \n"
  686. , (u32)info.buff[1]);
  687. break;
  688. case IOCTL_ISDBT_TS_START:
  689. ISDB_PR_DBG("IOCTL_ISDBT_TS_START \n");
  690. #ifdef TS_DROP_DEBUG
  691. #ifdef FEATURE_TS_CHECK
  692. create_tspacket_anal();
  693. check_cnt_size = 0;
  694. #endif
  695. #endif
  696. hOpen->isdbttype = TS_TYPE;
  697. break;
  698. case IOCTL_ISDBT_TS_STOP:
  699. ISDB_PR_DBG("IOCTL_ISDBT_TS_STOP \n");
  700. hOpen->isdbttype = 0;
  701. break;
  702. case IOCTL_ISDBT_POWER_ON:
  703. ISDB_PR_DBG("IOCTL_ISDBT_POWER_ON \n");
  704. isdbt_hw_init();
  705. res = bbm_com_probe(hInit, DIV_BROADCAST);
  706. if (res) {
  707. ISDB_PR_INFO("FC8300 IOCTL_ISDBT_POWER_ON FAIL \n");
  708. isdbt_hw_deinit();
  709. } else {
  710. ISDB_PR_INFO("FC8300 IOCTL_ISDBT_POWER_ON SUCCESS\n");
  711. }
  712. break;
  713. case IOCTL_ISDBT_POWER_OFF:
  714. ISDB_PR_DBG("IOCTL_ISDBT_POWER_OFF \n");
  715. isdbt_hw_deinit();
  716. break;
  717. case IOCTL_ISDBT_SCAN_STATUS:
  718. ISDB_PR_DBG("IOCTL_ISDBT_SCAN_STATUS \n");
  719. res = bbm_com_scan_status(hInit, DIV_BROADCAST);
  720. break;
  721. case IOCTL_ISDBT_TUNER_GET_RSSI:
  722. err = copy_from_user((void *)&info, (void *)arg, size);
  723. res = bbm_com_tuner_get_rssi(hInit
  724. , DIV_BROADCAST, (s32 *)&info.buff[0]);
  725. err |= copy_to_user((void *)arg, (void *)&info, size);
  726. break;
  727. case TUNER_IOCTL_VALGET_OPENCNT:
  728. res = tuner_ioctl_get_open_count ( filp->private_data,
  729. cmd,
  730. arg );
  731. break;
  732. case TUNER_IOCTL_VALSET_MONICNT:
  733. res = tuner_ioctl_set_monitor_mode ( filp->private_data,
  734. cmd,
  735. arg );
  736. break;
  737. default:
  738. ISDB_PR_INFO("isdbt ioctl error!\n");
  739. res = BBM_NOK;
  740. break;
  741. }
  742. if (err < 0) {
  743. ISDB_PR_INFO("copy to/from user fail : %d", err);
  744. res = BBM_NOK;
  745. }
  746. return res;
  747. }
  748. static struct isdbt_platform_data *isdbt_populate_dt_pdata(struct device *dev)
  749. {
  750. struct isdbt_platform_data *pdata;
  751. ISDB_PR_DBG("%s\n", __func__);
  752. pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
  753. if (!pdata) {
  754. ISDB_PR_ERR("%s : could not allocate memory for platform data\n", __func__);
  755. goto err;
  756. }
  757. pdata->gpio_en = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-pwr-en", 0);
  758. if (pdata->gpio_en < 0) {
  759. ISDB_PR_ERR("%s : can not find the isdbt-detect-gpio gpio_en in the dt\n", __func__);
  760. goto alloc_err;
  761. } else
  762. ISDB_PR_INFO("%s : isdbt-detect-gpio gpio_en =%d\n", __func__, pdata->gpio_en);
  763. pdata->gpio_rst = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-rst", 0);
  764. if (pdata->gpio_rst < 0) {
  765. ISDB_PR_ERR("%s : can not find the isdbt-detect-gpio gpio_rst in the dt\n", __func__);
  766. goto alloc_err;
  767. } else
  768. ISDB_PR_INFO("%s : isdbt-detect-gpio gpio_rst =%d\n", __func__, pdata->gpio_rst);
  769. pdata->gpio_int = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-irq", 0);
  770. if (pdata->gpio_int < 0) {
  771. ISDB_PR_ERR("%s : can not find the isdbt-detect-gpio in the gpio_int dt\n", __func__);
  772. goto alloc_err;
  773. } else
  774. ISDB_PR_INFO("%s : isdbt-detect-gpio gpio_int =%d\n", __func__, pdata->gpio_int);
  775. pdata->gpio_i2c_sda = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-i2c_sda", 0);
  776. if (pdata->gpio_i2c_sda < 0) {
  777. ISDB_PR_ERR("%s : can not find the isdbt-detect-gpio gpio_i2c_sda in the dt\n", __func__);
  778. goto alloc_err;
  779. } else
  780. ISDB_PR_INFO("%s : isdbt-detect-gpio gpio_i2c_sda=%d\n", __func__, pdata->gpio_i2c_sda);
  781. pdata->gpio_i2c_scl = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-i2c_scl", 0);
  782. if (pdata->gpio_i2c_scl < 0) {
  783. ISDB_PR_ERR("%s : can not find the isdbt-detect-gpio gpio_i2c_scl in the dt\n", __func__);
  784. goto alloc_err;
  785. } else
  786. ISDB_PR_INFO("%s : isdbt-detect-gpio gpio_i2c_scl=%d\n", __func__, pdata->gpio_i2c_scl);
  787. pdata->gpio_spi_do = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-spi_do", 0);
  788. if (pdata->gpio_spi_do < 0) {
  789. ISDB_PR_ERR("%s : can not find the isdbt-detect-gpio in the gpio_spi_do dt\n", __func__);
  790. goto alloc_err;
  791. } else
  792. ISDB_PR_INFO("%s : isdbt-detect-gpio gpio_spi_do =%d\n", __func__, pdata->gpio_spi_do);
  793. pdata->gpio_spi_di = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-spi_di", 0);
  794. if (pdata->gpio_spi_di < 0) {
  795. ISDB_PR_ERR("%s : can not find the isdbt-detect-gpio in the gpio_spi_di dt\n", __func__);
  796. goto alloc_err;
  797. } else
  798. ISDB_PR_INFO("%s : isdbt-detect-gpio gpio_spi_di =%d\n", __func__, pdata->gpio_spi_di);
  799. pdata->gpio_spi_cs = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-spi_cs", 0);
  800. if (pdata->gpio_spi_cs < 0) {
  801. ISDB_PR_ERR("%s : can not find the isdbt-detect-gpio gpio_spi_cs in the dt\n", __func__);
  802. goto alloc_err;
  803. } else
  804. ISDB_PR_INFO("%s : isdbt-detect-gpio gpio_spi_cs=%d\n", __func__, pdata->gpio_spi_cs);
  805. pdata->gpio_spi_clk = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-spi_clk", 0);
  806. if (pdata->gpio_spi_clk < 0) {
  807. ISDB_PR_ERR("%s : can not find the isdbt-detect-gpio gpio_spi_clk in the dt\n", __func__);
  808. goto alloc_err;
  809. } else
  810. ISDB_PR_INFO("%s : isdbt-detect-gpio gpio_spi_clk=%d\n", __func__, pdata->gpio_spi_clk);
  811. return pdata;
  812. alloc_err:
  813. devm_kfree(dev, pdata);
  814. err:
  815. return NULL;
  816. }
  817. static int isdbt_probe(struct platform_device *pdev)
  818. {
  819. int res=0;
  820. ISDB_PR_INFO("%s\n", __func__);
  821. open_cnt = 0;
  822. isdbt_pdata = isdbt_populate_dt_pdata(&pdev->dev);
  823. if (!isdbt_pdata) {
  824. ISDB_PR_ERR("%s : isdbt_pdata is NULL.\n", __func__);
  825. return -ENODEV;
  826. }
  827. isdbt_gpio_init();
  828. res = misc_register(&fc8300_misc_device);
  829. if (res < 0) {
  830. ISDB_PR_INFO("isdbt init fail : %d\n", res);
  831. return res;
  832. }
  833. hInit = kmalloc(sizeof(struct ISDBT_INIT_INFO_T), GFP_KERNEL);
  834. #if defined(BBM_I2C_TSIF) || defined(BBM_I2C_SPI)
  835. res = bbm_com_hostif_select(hInit, BBM_I2C);
  836. ISDB_PR_INFO("isdbt host interface select BBM_I2C!\n");
  837. #else
  838. ISDB_PR_INFO("isdbt host interface select BBM_SPI !\n");
  839. res = bbm_com_hostif_select(hInit, BBM_SPI);
  840. #endif
  841. if (res)
  842. ISDB_PR_INFO("isdbt host interface select fail!\n");
  843. #ifndef BBM_I2C_TSIF
  844. if (!isdbt_kthread) {
  845. ISDB_PR_INFO("kthread run\n");
  846. isdbt_kthread = kthread_run(isdbt_thread
  847. , (void *)hInit, "isdbt_thread");
  848. }
  849. #endif
  850. INIT_LIST_HEAD(&(hInit->hHead));
  851. return 0;
  852. }
  853. static int isdbt_remove(struct platform_device *pdev)
  854. {
  855. ISDB_PR_INFO("ISDBT remove\n");
  856. return 0;
  857. }
  858. static int isdbt_suspend(struct platform_device *pdev, pm_message_t mesg)
  859. {
  860. int value;
  861. value = gpio_get_value_cansleep(isdbt_pdata->gpio_en);
  862. ISDB_PR_DBG("%s value = %d\n",__func__,value);
  863. if(value == 1)
  864. {
  865. gpio_set_value(isdbt_pdata->gpio_en, 0);
  866. }
  867. return 0;
  868. }
  869. static int isdbt_resume(struct platform_device *pdev)
  870. {
  871. return 0;
  872. }
  873. static const struct of_device_id isdbt_match_table[] = {
  874. { .compatible = "isdb_fc8300_pdata",
  875. },
  876. {}
  877. };
  878. static struct platform_driver isdb_fc8300_driver = {
  879. .driver = {
  880. .owner = THIS_MODULE,
  881. .name = "isdbt",
  882. .of_match_table = isdbt_match_table,
  883. },
  884. .probe = isdbt_probe,
  885. .remove = isdbt_remove,
  886. .suspend = isdbt_suspend,
  887. .resume = isdbt_resume,
  888. };
  889. int isdbt_init(void)
  890. {
  891. s32 res;
  892. ISDB_PR_INFO("isdbt_fc8300_init started\n");
  893. // res = misc_register(&fc8300_misc_device);
  894. res = platform_driver_register(&isdb_fc8300_driver);
  895. if (res < 0) {
  896. ISDB_PR_INFO("isdbt init fail : %d\n", res);
  897. return res;
  898. }
  899. return 0;
  900. }
  901. void isdbt_exit(void)
  902. {
  903. ISDB_PR_INFO("isdb_fc8300_exit \n");
  904. #ifndef BBM_I2C_TSIF
  905. free_irq(gpio_to_irq(isdbt_pdata->gpio_int), NULL);
  906. gpio_free(isdbt_pdata->gpio_int);
  907. #endif
  908. gpio_free(isdbt_pdata->gpio_rst);
  909. gpio_free(isdbt_pdata->gpio_en);
  910. // gpio_free(isdbt_pdata->gpio_i2c_sda);
  911. // gpio_free(isdbt_pdata->gpio_i2c_scl);
  912. #ifndef BBM_I2C_TSIF
  913. if (isdbt_kthread)
  914. kthread_stop(isdbt_kthread);
  915. isdbt_kthread = NULL;
  916. #endif
  917. bbm_com_hostif_deselect(hInit);
  918. isdbt_hw_deinit();
  919. platform_driver_unregister(&isdb_fc8300_driver);
  920. misc_deregister(&fc8300_misc_device);
  921. if (hInit != NULL)
  922. kfree(hInit);
  923. }
  924. module_init(isdbt_init);
  925. module_exit(isdbt_exit);
  926. MODULE_LICENSE("Dual BSD/GPL");