fc8150.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221
  1. #include <linux/module.h>
  2. #include <linux/miscdevice.h>
  3. #include <linux/interrupt.h>
  4. #include <linux/kthread.h>
  5. #include <linux/poll.h>
  6. #include <linux/vmalloc.h>
  7. #include <linux/irq.h>
  8. #include <linux/delay.h>
  9. #include <linux/slab.h>
  10. #include <linux/gpio.h>
  11. #include <linux/spmi.h>
  12. #include <linux/io.h>
  13. #include <mach/isdbt_pdata.h>
  14. #include <mach/gpio.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/wakelock.h>
  17. #include <linux/input.h>
  18. #include <mach/gpiomux.h>
  19. #include <linux/of_gpio.h>
  20. #if defined(CONFIG_ISDBT_ANT_DET)
  21. static struct wake_lock isdbt_ant_wlock;
  22. #endif
  23. #include "fc8150.h"
  24. #include "bbm.h"
  25. #include "fci_oal.h"
  26. #include "fci_tun.h"
  27. #include "fc8150_regs.h"
  28. #include "fc8150_isr.h"
  29. #include "fci_hal.h"
  30. #include <asm/system_info.h>
  31. struct ISDBT_INIT_INFO_T *hInit;
  32. #define RING_BUFFER_SIZE (128 * 1024) /* kmalloc max 128k */
  33. /* GPIO(RESET & INTRRUPT) Setting */
  34. #define FC8150_NAME "isdbt"
  35. static struct isdbt_platform_data *isdbt_pdata;
  36. u8 static_ringbuffer[RING_BUFFER_SIZE];
  37. enum ISDBT_MODE driver_mode = ISDBT_POWEROFF;
  38. static DEFINE_MUTEX(ringbuffer_lock);
  39. static DECLARE_WAIT_QUEUE_HEAD(isdbt_isr_wait);
  40. static u8 isdbt_isr_sig;
  41. static struct task_struct *isdbt_kthread;
  42. #ifdef CONFIG_ISDBT_SPMI
  43. static unsigned int spmi_addr;
  44. #endif
  45. void isdbt_hw_start(void);
  46. void isdbt_hw_stop(void);
  47. #ifdef CONFIG_ISDBT_SPMI
  48. struct isdbt_qpnp_data
  49. {
  50. struct spmi_device *spmi;
  51. };
  52. static struct isdbt_qpnp_data *isdbt_spmi;
  53. static int __devinit qpnp_isdbt_clk_probe(struct spmi_device *spmi)
  54. {
  55. int rc;
  56. u8 reg = 0x00;
  57. struct isdbt_qpnp_data *spmi_data;
  58. printk("%s called\n", __func__);
  59. spmi_data = devm_kzalloc(&spmi->dev, sizeof(spmi_data), GFP_KERNEL);
  60. if(!spmi_data)
  61. return -ENOMEM;
  62. spmi_data->spmi = spmi;
  63. isdbt_spmi = spmi_data;
  64. if(system_rev >= 9)
  65. {
  66. spmi_addr = 0x5546;
  67. }
  68. else
  69. {
  70. spmi_addr = 0x5246;
  71. }
  72. rc = spmi_ext_register_readl(spmi->ctrl, spmi->sid, spmi_addr, &reg, 1);
  73. if (rc) {
  74. printk("Unable to read from addr=0x%x, rc(%d)\n", spmi_addr, rc);
  75. }
  76. printk("%s Register 0x%x contains 0x%x\n", __func__,spmi_addr, reg);
  77. return 0;
  78. }
  79. static int __devexit qpnp_isdbt_clk_remove(struct spmi_device *spmi)
  80. {
  81. u8 reg = 0x00;
  82. int rc = spmi_ext_register_writel(spmi->ctrl, spmi->sid, spmi_addr,&reg, 1);
  83. if (rc) {
  84. printk("Unable to write from addr=%x, rc(%d)\n", spmi_addr, rc);
  85. }
  86. return 0;
  87. }
  88. static struct of_device_id spmi_match_table[] = {
  89. {
  90. .compatible = "qcom,qpnp-clkrf2"
  91. },
  92. {
  93. .compatible = "qcom,qpnp-clkbb2"
  94. }
  95. };
  96. static struct spmi_driver qpnp_isdbt_clk_driver = {
  97. .driver = {
  98. .name = "qcom,qpnp-isdbclk",
  99. .of_match_table = spmi_match_table,
  100. },
  101. .probe = qpnp_isdbt_clk_probe,
  102. .remove = __devexit_p(qpnp_isdbt_clk_remove),
  103. };
  104. #endif
  105. static irqreturn_t isdbt_irq(int irq, void *dev_id)
  106. {
  107. isdbt_isr_sig = 1;
  108. wake_up_interruptible(&isdbt_isr_wait);
  109. return IRQ_HANDLED;
  110. }
  111. int isdbt_hw_setting(void)
  112. {
  113. int err;
  114. printk("isdbt_hw_setting\n");
  115. err = gpio_request(isdbt_pdata->gpio_en, "isdbt_en");
  116. if (err) {
  117. printk("isdbt_hw_setting: Couldn't request isdbt_en\n");
  118. goto ISBT_EN_ERR;
  119. }
  120. gpio_direction_output(isdbt_pdata->gpio_en, 0); //moved to hw_init
  121. err = gpio_request(isdbt_pdata->gpio_rst, "isdbt_rst");
  122. if (err) {
  123. printk("isdbt_hw_setting: Couldn't request isdbt_rst\n");
  124. goto ISDBT_RST_ERR;
  125. }
  126. gpio_direction_output(isdbt_pdata->gpio_rst, 1);
  127. err = gpio_request(isdbt_pdata->gpio_int, "isdbt_irq");
  128. if (err) {
  129. printk("isdbt_hw_setting: Couldn't request isdbt_irq\n");
  130. goto ISDBT_INT_ERR;
  131. }
  132. // gpio_direction_input(isdbt_pdata->gpio_int);
  133. #ifdef CONFIG_ISDBT_ANT_DET
  134. err = gpio_request(isdbt_pdata->gpio_ant_det, "gpio_ant_det");
  135. if (err) {
  136. printk("isdbt_hw_setting: Couldn't request gpio_ant_det\n");
  137. goto ISDBT_ANT_DET_ERR;
  138. }
  139. // gpio_direction_input(isdbt_pdata->gpio_ant_det);
  140. #endif
  141. return 0;
  142. #ifdef CONFIG_ISDBT_ANT_DET
  143. ISDBT_ANT_DET_ERR:
  144. gpio_free(isdbt_pdata->gpio_int);
  145. #endif
  146. ISDBT_INT_ERR:
  147. gpio_free(isdbt_pdata->gpio_rst);
  148. ISDBT_RST_ERR:
  149. gpio_free(isdbt_pdata->gpio_en);
  150. ISBT_EN_ERR:
  151. return err;
  152. }
  153. static void isdbt_gpio_init(void)
  154. {
  155. printk("%s\n",__func__);
  156. #ifdef CONFIG_ISDBT_FC8150_HKDI
  157. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_spi_di, GPIOMUX_FUNC_1,
  158. GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
  159. GPIO_CFG_ENABLE);
  160. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_spi_do, GPIOMUX_FUNC_1,
  161. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
  162. GPIO_CFG_ENABLE);
  163. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_spi_cs, GPIOMUX_FUNC_1,
  164. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
  165. GPIO_CFG_ENABLE);
  166. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_spi_clk, GPIOMUX_FUNC_1,
  167. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
  168. GPIO_CFG_ENABLE);
  169. #endif
  170. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_en, GPIOMUX_FUNC_GPIO,
  171. GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
  172. GPIO_CFG_ENABLE);
  173. //gpio_set_value(isdbt_pdata->gpio_en, 0);
  174. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_rst, GPIOMUX_FUNC_GPIO,
  175. GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
  176. GPIO_CFG_ENABLE);
  177. //gpio_set_value(isdbt_pdata->gpio_rst, 0);
  178. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_int, GPIOMUX_FUNC_GPIO,
  179. GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
  180. GPIO_CFG_ENABLE);
  181. isdbt_hw_setting();
  182. }
  183. /*POWER_ON & HW_RESET & INTERRUPT_CLEAR */
  184. void isdbt_hw_init(void)
  185. {
  186. int i = 0;
  187. while (driver_mode == ISDBT_DATAREAD) {
  188. msWait(100);
  189. if (i++ > 5)
  190. break;
  191. }
  192. printk("%s START\n", __func__);
  193. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_int, GPIOMUX_FUNC_GPIO,
  194. GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
  195. GPIO_CFG_ENABLE);
  196. #ifdef CONFIG_ISDBT_ANT_DET
  197. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_ant_det, GPIOMUX_FUNC_GPIO,
  198. GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
  199. GPIO_CFG_ENABLE);
  200. #endif
  201. isdbt_hw_start();
  202. }
  203. void isdbt_hw_start(void)
  204. {
  205. #ifdef CONFIG_ISDBT_SPMI
  206. u8 reg = 0x00;
  207. #endif
  208. #ifdef CONFIG_ISDBT_ANT_DET
  209. gpio_direction_input(isdbt_pdata->gpio_ant_det);
  210. #endif
  211. //gpio_direction_output(isdbt_pdata->gpio_en, 1);
  212. gpio_set_value(isdbt_pdata->gpio_en, 1);
  213. gpio_direction_input(isdbt_pdata->gpio_int);
  214. //gpio_direction_output(isdbt_pdata->gpio_rst, 1);
  215. //gpio_set_value(isdbt_pdata->gpio_rst, 1);
  216. mdelay(3);
  217. #ifdef CONFIG_ISDBT_SPMI
  218. printk("%s, Enabling ISDBT_CLK\n", __func__);
  219. printk("%s Writing 0x80 to register 0x5246\n", __func__);
  220. reg = 0x80;
  221. if(isdbt_spmi)
  222. {
  223. int rc = spmi_ext_register_writel(isdbt_spmi->spmi->ctrl, isdbt_spmi->spmi->sid, spmi_addr,&reg, 1);
  224. if (rc) {
  225. printk("%s, Unable to write from addr=0x%x, rc(%d)\n", __func__, spmi_addr, rc);
  226. }
  227. }
  228. else
  229. printk("%s ERROR !! isdbt_spmi is NULL !!\n", __func__);
  230. #endif
  231. udelay(600);
  232. //mdelay(5); // removed
  233. gpio_set_value(isdbt_pdata->gpio_rst, 0);
  234. mdelay(1);
  235. gpio_set_value(isdbt_pdata->gpio_rst, 1);
  236. driver_mode = ISDBT_POWERON;
  237. printk("%s \n END. driver_mode=%d ", __func__, driver_mode);
  238. }
  239. /*POWER_OFF */
  240. void isdbt_hw_stop(void)
  241. {
  242. #ifdef CONFIG_ISDBT_SPMI
  243. u8 reg = 0x00;
  244. #endif
  245. printk("%st\n", __func__);
  246. driver_mode = ISDBT_POWEROFF;
  247. #ifdef CONFIG_ISDBT_SPMI
  248. printk("%s, Tuning ISDBT_CLK off\n", __func__);
  249. printk("%s Writing 0x00 to register 0x%x\n", __func__, spmi_addr);
  250. reg = 0x00;
  251. if(isdbt_spmi)
  252. {
  253. int rc = spmi_ext_register_writel(isdbt_spmi->spmi->ctrl, isdbt_spmi->spmi->sid, spmi_addr,&reg, 1);
  254. if (rc) {
  255. printk("%s, Unable to write from addr=%x, rc(%d)\n", __func__, spmi_addr, rc );
  256. }
  257. }
  258. else
  259. printk("%s ERROR !! isdbt_spmi is NULL !!\n", __func__);
  260. #endif
  261. gpio_set_value(isdbt_pdata->gpio_en, 0);
  262. }
  263. void isdbt_hw_deinit(void)
  264. {
  265. printk("isdbt_hw_deinit\n");
  266. isdbt_hw_stop();
  267. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_int, GPIOMUX_FUNC_GPIO,
  268. GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
  269. GPIO_CFG_ENABLE);
  270. #ifdef CONFIG_ISDBT_ANT_DET
  271. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_ant_det, GPIOMUX_FUNC_GPIO,
  272. GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
  273. GPIO_CFG_ENABLE);
  274. #endif
  275. }
  276. int data_callback(u32 hDevice, u8 *data, int len)
  277. {
  278. struct ISDBT_INIT_INFO_T *hInit;
  279. struct list_head *temp;
  280. hInit = (struct ISDBT_INIT_INFO_T *)hDevice;
  281. list_for_each(temp, &(hInit->hHead))
  282. {
  283. struct ISDBT_OPEN_INFO_T *hOpen;
  284. hOpen = list_entry(temp, struct ISDBT_OPEN_INFO_T, hList);
  285. if (hOpen->isdbttype == TS_TYPE) {
  286. mutex_lock(&ringbuffer_lock);
  287. if (fci_ringbuffer_free(&hOpen->RingBuffer) < len) {
  288. /*PRINTF(hDevice, "f"); */
  289. /* return 0 */;
  290. FCI_RINGBUFFER_SKIP(&hOpen->RingBuffer, len);
  291. }
  292. fci_ringbuffer_write(&hOpen->RingBuffer, data, len);
  293. wake_up_interruptible(&(hOpen->RingBuffer.queue));
  294. mutex_unlock(&ringbuffer_lock);
  295. }
  296. }
  297. return 0;
  298. }
  299. static int isdbt_thread(void *hDevice)
  300. {
  301. struct ISDBT_INIT_INFO_T *hInit = (struct ISDBT_INIT_INFO_T *)hDevice;
  302. set_user_nice(current, -20);
  303. BBM_TS_CALLBACK_REGISTER((u32)hInit, data_callback);
  304. while (1) {
  305. wait_event_interruptible(isdbt_isr_wait,
  306. isdbt_isr_sig || kthread_should_stop());
  307. if (driver_mode == ISDBT_POWERON) {
  308. driver_mode = ISDBT_DATAREAD;
  309. BBM_ISR(hInit);
  310. driver_mode = ISDBT_POWERON;
  311. }
  312. isdbt_isr_sig = 0;
  313. if (kthread_should_stop())
  314. break;
  315. }
  316. BBM_TS_CALLBACK_DEREGISTER();
  317. PRINTF(hInit, "isdbt_kthread exit\n");
  318. return 0;
  319. }
  320. const struct file_operations isdbt_fops = {
  321. .owner = THIS_MODULE,
  322. .unlocked_ioctl = isdbt_ioctl,
  323. .open = isdbt_open,
  324. .read = isdbt_read,
  325. .release = isdbt_release,
  326. };
  327. static struct miscdevice fc8150_misc_device = {
  328. .minor = MISC_DYNAMIC_MINOR,
  329. .name = FC8150_NAME,
  330. .fops = &isdbt_fops,
  331. };
  332. int isdbt_open(struct inode *inode, struct file *filp)
  333. {
  334. struct ISDBT_OPEN_INFO_T *hOpen;
  335. printk("isdbt_open. \n");
  336. hOpen = kmalloc(sizeof(struct ISDBT_OPEN_INFO_T), GFP_KERNEL);
  337. // hOpen->buf = kmalloc(RING_BUFFER_SIZE, GFP_KERNEL); //Fix for PLM P140326-05955
  338. hOpen->buf = &static_ringbuffer[0];
  339. hOpen->isdbttype = 0;
  340. list_add(&(hOpen->hList), &(hInit->hHead));
  341. hOpen->hInit = (HANDLE *)hInit;
  342. if (hOpen->buf == NULL) {
  343. PRINTF(hInit, "ring buffer malloc error\n");
  344. return -ENOMEM;
  345. }
  346. fci_ringbuffer_init(&hOpen->RingBuffer, hOpen->buf, RING_BUFFER_SIZE);
  347. filp->private_data = hOpen;
  348. return 0;
  349. }
  350. ssize_t isdbt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
  351. {
  352. s32 avail;
  353. s32 non_blocking = filp->f_flags & O_NONBLOCK;
  354. struct ISDBT_OPEN_INFO_T *hOpen
  355. = (struct ISDBT_OPEN_INFO_T *)filp->private_data;
  356. struct fci_ringbuffer *cibuf = &hOpen->RingBuffer;
  357. ssize_t len, read_len = 0;
  358. if (!cibuf->data || !count) {
  359. // printk("isdbt_read read 0\n");
  360. return 0;
  361. }
  362. if (non_blocking && (fci_ringbuffer_empty(cibuf))) {
  363. /*PRINTF(hInit, "return EWOULDBLOCK\n"); */
  364. return -EWOULDBLOCK;
  365. }
  366. if (wait_event_interruptible(cibuf->queue,
  367. !fci_ringbuffer_empty(cibuf))) {
  368. printk("isdbt_read return ERESTARTSYS\n");
  369. return -ERESTARTSYS;
  370. }
  371. mutex_lock(&ringbuffer_lock);
  372. avail = fci_ringbuffer_avail(cibuf);
  373. if (count >= avail)
  374. len = avail;
  375. else
  376. len = count - (count % 188);
  377. read_len = fci_ringbuffer_read_user(cibuf, buf, len);
  378. mutex_unlock(&ringbuffer_lock);
  379. return read_len;
  380. }
  381. int isdbt_release(struct inode *inode, struct file *filp)
  382. {
  383. struct ISDBT_OPEN_INFO_T *hOpen;
  384. PRINTF(hInit, "isdbt_release\n");
  385. hOpen = filp->private_data;
  386. hOpen->isdbttype = 0;
  387. list_del(&(hOpen->hList));
  388. /* kfree(hOpen->buf); */
  389. kfree(hOpen);
  390. return 0;
  391. }
  392. int fc8150_if_test(void)
  393. {
  394. int res = 0;
  395. int i;
  396. u16 wdata = 0;
  397. u32 ldata = 0;
  398. u8 data = 0;
  399. u8 temp = 0;
  400. printk("fc8150_if_test Start!!!\n");
  401. for (i = 0 ; i < 100 ; i++) {
  402. BBM_BYTE_WRITE(0, 0xa4, i & 0xff);
  403. BBM_BYTE_READ(0, 0xa4, &data);
  404. if ((i & 0xff) != data) {
  405. printk("fc8150_if_btest! i=0x%x, data=0x%x\n"
  406. , i & 0xff, data);
  407. res = 1;
  408. }
  409. }
  410. for (i = 0 ; i < 100 ; i++) {
  411. BBM_WORD_WRITE(0, 0xa4, i & 0xffff);
  412. BBM_WORD_READ(0, 0xa4, &wdata);
  413. if ((i & 0xffff) != wdata) {
  414. printk("fc8150_if_wtest! i=0x%x, data=0x%x\n"
  415. , i & 0xffff, wdata);
  416. res = 1;
  417. }
  418. }
  419. for (i = 0 ; i < 100 ; i++) {
  420. BBM_LONG_WRITE(0, 0xa4, i & 0xffffffff);
  421. BBM_LONG_READ(0, 0xa4, &ldata);
  422. if ((i & 0xffffffff) != ldata) {
  423. printk("fc8150_if_ltest! i=0x%x, data=0x%x\n"
  424. , i & 0xffffffff, ldata);
  425. res = 1;
  426. }
  427. }
  428. for (i = 0 ; i < 100 ; i++) {
  429. temp = i & 0xff;
  430. BBM_TUNER_WRITE(NULL, 0x52, 0x01, &temp, 0x01);
  431. BBM_TUNER_READ(NULL, 0x52, 0x01, &data, 0x01);
  432. if ((i & 0xff) != data)
  433. printk("FC8150 tuner test (0x%x,0x%x)\n"
  434. , i & 0xff, data);
  435. }
  436. printk("fc8150_if_test End!!!\n");
  437. return res;
  438. }
  439. void isdbt_isr_check(HANDLE hDevice)
  440. {
  441. u8 isr_time = 0;
  442. BBM_WRITE(hDevice, BBM_BUF_INT, 0x00);
  443. while (isr_time < 10) {
  444. if (!isdbt_isr_sig)
  445. break;
  446. msWait(10);
  447. isr_time++;
  448. }
  449. }
  450. long isdbt_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  451. {
  452. s32 res = BBM_NOK;
  453. s32 err = 0;
  454. s32 size = 0;
  455. struct ISDBT_OPEN_INFO_T *hOpen;
  456. struct ioctl_info info;
  457. if (_IOC_TYPE(cmd) != IOCTL_MAGIC)
  458. return -EINVAL;
  459. if (_IOC_NR(cmd) >= IOCTL_MAXNR)
  460. return -EINVAL;
  461. hOpen = filp->private_data;
  462. size = _IOC_SIZE(cmd);
  463. switch (cmd) {
  464. case IOCTL_ISDBT_RESET:
  465. printk("IOCTL_ISDBT_RESET\n");
  466. res = BBM_RESET(hInit);
  467. break;
  468. case IOCTL_ISDBT_INIT:
  469. //printk("IOCTL_ISDBT_INIT\n");
  470. res = BBM_I2C_INIT(hInit, FCI_I2C_TYPE);
  471. res |= BBM_PROBE(hInit);
  472. if (res) {
  473. PRINTF(hInit, "FC8150 Initialize Fail \n");
  474. break;
  475. }
  476. res |= BBM_INIT(hInit);
  477. break;
  478. case IOCTL_ISDBT_BYTE_READ:
  479. //printk("IOCTL_ISDBT_BYTE_READ\n");
  480. err = copy_from_user((void *)&info, (void *)arg, size);
  481. res = BBM_BYTE_READ(hInit, (u16)info.buff[0]
  482. , (u8 *)(&info.buff[1]));
  483. err |= copy_to_user((void *)arg, (void *)&info, size);
  484. break;
  485. case IOCTL_ISDBT_WORD_READ:
  486. //printk("IOCTL_ISDBT_WORD_READ\n");
  487. err = copy_from_user((void *)&info, (void *)arg, size);
  488. res = BBM_WORD_READ(hInit, (u16)info.buff[0]
  489. , (u16 *)(&info.buff[1]));
  490. err |= copy_to_user((void *)arg, (void *)&info, size);
  491. break;
  492. case IOCTL_ISDBT_LONG_READ:
  493. //printk("IOCTL_ISDBT_LONG_READ\n");
  494. err = copy_from_user((void *)&info, (void *)arg, size);
  495. res = BBM_LONG_READ(hInit, (u16)info.buff[0]
  496. , (u32 *)(&info.buff[1]));
  497. err |= copy_to_user((void *)arg, (void *)&info, size);
  498. break;
  499. case IOCTL_ISDBT_BULK_READ:
  500. //printk("IOCTL_ISDBT_BULK_READ\n");
  501. err = copy_from_user((void *)&info, (void *)arg, size);
  502. res = BBM_BULK_READ(hInit, (u16)info.buff[0]
  503. , (u8 *)(&info.buff[2]), info.buff[1]);
  504. err |= copy_to_user((void *)arg, (void *)&info, size);
  505. break;
  506. case IOCTL_ISDBT_BYTE_WRITE:
  507. //printk("IOCTL_ISDBT_BYTE_WRITE\n");
  508. err = copy_from_user((void *)&info, (void *)arg, size);
  509. res = BBM_BYTE_WRITE(hInit, (u16)info.buff[0]
  510. , (u8)info.buff[1]);
  511. break;
  512. case IOCTL_ISDBT_WORD_WRITE:
  513. //printk("IOCTL_ISDBT_WORD_WRITE\n");
  514. err = copy_from_user((void *)&info, (void *)arg, size);
  515. res = BBM_WORD_WRITE(hInit, (u16)info.buff[0]
  516. , (u16)info.buff[1]);
  517. break;
  518. case IOCTL_ISDBT_LONG_WRITE:
  519. //printk("IOCTL_ISDBT_LONG_WRITE\n");
  520. err = copy_from_user((void *)&info, (void *)arg, size);
  521. res = BBM_LONG_WRITE(hInit, (u16)info.buff[0]
  522. , (u32)info.buff[1]);
  523. break;
  524. case IOCTL_ISDBT_BULK_WRITE:
  525. //printk("IOCTL_ISDBT_BULK_WRITE\n");
  526. err = copy_from_user((void *)&info, (void *)arg, size);
  527. res = BBM_BULK_WRITE(hInit, (u16)info.buff[0]
  528. , (u8 *)(&info.buff[2]), info.buff[1]);
  529. break;
  530. case IOCTL_ISDBT_TUNER_READ:
  531. printk("IOCTL_ISDBT_TUNER_READ\n");
  532. err = copy_from_user((void *)&info, (void *)arg, size);
  533. res = BBM_TUNER_READ(hInit, (u8)info.buff[0]
  534. , (u8)info.buff[1], (u8 *)(&info.buff[3])
  535. , (u8)info.buff[2]);
  536. err |= copy_to_user((void *)arg, (void *)&info, size);
  537. break;
  538. case IOCTL_ISDBT_TUNER_WRITE:
  539. printk("isdb IOCTL_ISDBT_TUNER_WRITE\n");
  540. err = copy_from_user((void *)&info, (void *)arg, size);
  541. res = BBM_TUNER_WRITE(hInit, (u8)info.buff[0]
  542. , (u8)info.buff[1], (u8 *)(&info.buff[3])
  543. , (u8)info.buff[2]);
  544. break;
  545. case IOCTL_ISDBT_TUNER_SET_FREQ:
  546. printk("isdb IOCTL_ISDBT_TUNER_SET_FREQ\n");
  547. {
  548. u32 f_rf;
  549. err = copy_from_user((void *)&info, (void *)arg, size);
  550. f_rf = ((u32)info.buff[0] - 13) * 6000 + 473143;
  551. isdbt_isr_check(hInit);
  552. res = BBM_TUNER_SET_FREQ(hInit, f_rf);
  553. mutex_lock(&ringbuffer_lock);
  554. fci_ringbuffer_flush(&hOpen->RingBuffer);
  555. mutex_unlock(&ringbuffer_lock);
  556. BBM_WRITE(hInit, BBM_BUF_INT, 0x01);
  557. }
  558. break;
  559. case IOCTL_ISDBT_TUNER_SELECT:
  560. printk("isdb IOCTL_ISDBT_TUNER_SELECT\n");
  561. err = copy_from_user((void *)&info, (void *)arg, size);
  562. res = BBM_TUNER_SELECT(hInit, (u32)info.buff[0], 0);
  563. break;
  564. case IOCTL_ISDBT_TS_START:
  565. printk("isdb IOCTL_ISDBT_TS_START\n");
  566. hOpen->isdbttype = TS_TYPE;
  567. break;
  568. case IOCTL_ISDBT_TS_STOP:
  569. printk("isdb IOCTL_ISDBT_TS_STOP\n");
  570. hOpen->isdbttype = 0;
  571. break;
  572. case IOCTL_ISDBT_POWER_ON:
  573. printk("isdb ioctl IOCTL_ISDBT_POWER_ON\n");
  574. isdbt_hw_init();
  575. break;
  576. case IOCTL_ISDBT_POWER_OFF:
  577. printk("isdb ioctl IOCTL_ISDBT_POWER_OFF\n");
  578. isdbt_hw_deinit();
  579. break;
  580. case IOCTL_ISDBT_SCAN_STATUS:
  581. printk("isdb ioctl IOCTL_ISDBT_SCAN_STATUS\n");
  582. res = BBM_SCAN_STATUS(hInit);
  583. break;
  584. case IOCTL_ISDBT_TUNER_GET_RSSI:
  585. err = copy_from_user((void *)&info, (void *)arg, size);
  586. res = BBM_TUNER_GET_RSSI(hInit, (s32 *)&info.buff[0]);
  587. err |= copy_to_user((void *)arg, (void *)&info, size);
  588. break;
  589. default:
  590. PRINTF(hInit, "isdbt ioctl error!\n");
  591. res = BBM_NOK;
  592. break;
  593. }
  594. if (err < 0) {
  595. PRINTF(hInit, "copy to/from user fail : %d", err);
  596. res = BBM_NOK;
  597. }
  598. return res;
  599. }
  600. #if defined(CONFIG_ISDBT_ANT_DET)
  601. enum {
  602. ISDBT_ANT_OPEN = 0,
  603. ISDBT_ANT_CLOSE,
  604. ISDBT_ANT_UNKNOWN,
  605. };
  606. enum {
  607. ISDBT_ANT_DET_LOW = 0,
  608. ISDBT_ANT_DET_HIGH,
  609. };
  610. static struct input_dev *isdbt_ant_input;
  611. static int isdbt_check_ant;
  612. static int ant_prev_status;
  613. #define ISDBT_ANT_CHECK_DURATION 500000 /* us */
  614. #define ISDBT_ANT_CHECK_COUNT 2
  615. #define ISDBT_ANT_WLOCK_TIMEOUT \
  616. ((ISDBT_ANT_CHECK_DURATION * ISDBT_ANT_CHECK_COUNT * 2) / 1000000)
  617. static int isdbt_ant_det_check_value(void)
  618. {
  619. int loop = 0;
  620. int cur_val = 0, prev_val = 0;
  621. int ret = ISDBT_ANT_UNKNOWN;
  622. isdbt_check_ant = 1;
  623. prev_val = \
  624. ant_prev_status ? ISDBT_ANT_DET_LOW : ISDBT_ANT_DET_HIGH;
  625. for (loop = 0; loop < ISDBT_ANT_CHECK_COUNT; loop++) {
  626. usleep_range(ISDBT_ANT_CHECK_DURATION, ISDBT_ANT_CHECK_DURATION);
  627. cur_val = gpio_get_value_cansleep(isdbt_pdata->gpio_ant_det);
  628. if (prev_val != cur_val || ant_prev_status == cur_val)
  629. break;
  630. prev_val = cur_val;
  631. }
  632. if (loop == ISDBT_ANT_CHECK_COUNT) {
  633. if (ant_prev_status == ISDBT_ANT_DET_LOW
  634. && cur_val == ISDBT_ANT_DET_HIGH) {
  635. ret = ISDBT_ANT_OPEN;
  636. } else if (ant_prev_status == ISDBT_ANT_DET_HIGH
  637. && cur_val == ISDBT_ANT_DET_LOW) {
  638. ret = ISDBT_ANT_CLOSE;
  639. }
  640. ant_prev_status = cur_val;
  641. }
  642. isdbt_check_ant = 0;
  643. printk("%s cnt(%d) cur(%d) prev(%d)\n",
  644. __func__, loop, cur_val, ant_prev_status);
  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("%s: input device is not registered\n", __func__);
  657. return;
  658. }
  659. switch (isdbt_ant_det_check_value()) {
  660. case ISDBT_ANT_OPEN:
  661. input_report_key(isdbt_ant_input, KEY_DMB_ANT_DET_UP, 1);
  662. input_report_key(isdbt_ant_input, KEY_DMB_ANT_DET_UP, 0);
  663. input_sync(isdbt_ant_input);
  664. printk("%s : ISDBT_ANT_OPEN\n", __func__);
  665. break;
  666. case ISDBT_ANT_CLOSE:
  667. input_report_key(isdbt_ant_input, KEY_DMB_ANT_DET_DOWN, 1);
  668. input_report_key(isdbt_ant_input, KEY_DMB_ANT_DET_DOWN, 0);
  669. input_sync(isdbt_ant_input);
  670. printk("%s : ISDBT_ANT_CLOSE\n", __func__);
  671. break;
  672. case ISDBT_ANT_UNKNOWN:
  673. printk("%s : ISDBT_ANT_UNKNOWN\n", __func__);
  674. break;
  675. default:
  676. break;
  677. }
  678. }
  679. static struct workqueue_struct *isdbt_ant_det_wq;
  680. static DECLARE_WORK(isdbt_ant_det_work, isdbt_ant_det_work_func);
  681. static bool isdbt_ant_det_reg_input(struct platform_device *pdev)
  682. {
  683. struct input_dev *input;
  684. int err;
  685. printk("%s\n", __func__);
  686. input = input_allocate_device();
  687. if (!input) {
  688. printk("Can't allocate input device\n");
  689. err = -ENOMEM;
  690. }
  691. set_bit(EV_KEY, input->evbit);
  692. set_bit(KEY_DMB_ANT_DET_UP & KEY_MAX, input->keybit);
  693. set_bit(KEY_DMB_ANT_DET_DOWN & KEY_MAX, input->keybit);
  694. input->name = "sec_dmb_key";
  695. input->phys = "sec_dmb_key/input0";
  696. input->dev.parent = &pdev->dev;
  697. err = input_register_device(input);
  698. if (err) {
  699. printk("Can't register dmb_ant_det key: %d\n", err);
  700. goto free_input_dev;
  701. }
  702. isdbt_ant_input = input;
  703. ant_prev_status = gpio_get_value_cansleep(isdbt_pdata->gpio_ant_det);
  704. return true;
  705. free_input_dev:
  706. input_free_device(input);
  707. return false;
  708. }
  709. static void isdbt_ant_det_unreg_input(void)
  710. {
  711. //printk("%s\n", __func__);
  712. input_unregister_device(isdbt_ant_input);
  713. }
  714. static bool isdbt_ant_det_create_wq(void)
  715. {
  716. printk("%s\n", __func__);
  717. isdbt_ant_det_wq = create_singlethread_workqueue("isdbt_ant_det_wq");
  718. if (isdbt_ant_det_wq)
  719. return true;
  720. else
  721. return false;
  722. }
  723. static bool isdbt_ant_det_destroy_wq(void)
  724. {
  725. //printk("%s\n", __func__);
  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. if (isdbt_ant_det_ignore_irq())
  736. return IRQ_HANDLED;
  737. wake_lock_timeout(&isdbt_ant_wlock, ISDBT_ANT_WLOCK_TIMEOUT * HZ);
  738. if (isdbt_ant_det_wq) {
  739. int ret = 0;
  740. ret = queue_work(isdbt_ant_det_wq, &isdbt_ant_det_work);
  741. if (ret == 0)
  742. printk("%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. //printk("%s\n", __func__);
  750. if (set) {
  751. int irq_ret;
  752. isdbt_pdata->irq_ant_det = gpio_to_irq(isdbt_pdata->gpio_ant_det);
  753. irq_set_irq_type(isdbt_pdata->irq_ant_det, IRQ_TYPE_EDGE_BOTH);
  754. irq_ret = request_irq(isdbt_pdata->irq_ant_det
  755. , isdbt_ant_det_irq_handler
  756. , IRQF_DISABLED
  757. , "isdbt_ant_det"
  758. , NULL);
  759. if (irq_ret < 0) {
  760. printk("%s %d\r\n", __func__, irq_ret);
  761. ret = false;
  762. }
  763. enable_irq_wake(isdbt_pdata->irq_ant_det);
  764. } else {
  765. disable_irq_wake(isdbt_pdata->irq_ant_det);
  766. free_irq(isdbt_pdata->irq_ant_det, NULL);
  767. }
  768. return ret;
  769. }
  770. #endif
  771. static struct isdbt_platform_data *isdbt_populate_dt_pdata(struct device *dev)
  772. {
  773. struct isdbt_platform_data *pdata;
  774. printk("%s\n", __func__);
  775. pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
  776. if (!pdata) {
  777. pr_err("%s : could not allocate memory for platform data\n", __func__);
  778. goto err;
  779. }
  780. #ifdef CONFIG_ISDBT_ANT_DET
  781. pdata->gpio_ant_det = of_get_named_gpio(dev->of_node, "qcom,isdb-ant-det-gpio", 0);
  782. if (pdata->gpio_ant_det < 0) {
  783. pr_err("%s : can not find the isdbt-detect-gpio gpio_ant_det in the dt\n", __func__);
  784. goto alloc_err;
  785. } else
  786. pr_info("%s : isdbt-detect-gpio gpio_ant_det =%d\n", __func__, pdata->gpio_ant_det);
  787. #endif
  788. pdata->gpio_en = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-pwr-en", 0);
  789. if (pdata->gpio_en < 0) {
  790. pr_err("%s : can not find the isdbt-detect-gpio gpio_en in the dt\n", __func__);
  791. goto alloc_err;
  792. } else
  793. pr_info("%s : isdbt-detect-gpio gpio_en =%d\n", __func__, pdata->gpio_en);
  794. pdata->gpio_rst = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-rst", 0);
  795. if (pdata->gpio_rst < 0) {
  796. pr_err("%s : can not find the isdbt-detect-gpio gpio_rst in the dt\n", __func__);
  797. goto alloc_err;
  798. } else
  799. pr_info("%s : isdbt-detect-gpio gpio_rst =%d\n", __func__, pdata->gpio_rst);
  800. pdata->gpio_int = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-irq", 0);
  801. if (pdata->gpio_int < 0) {
  802. pr_err("%s : can not find the isdbt-detect-gpio in the gpio_int dt\n", __func__);
  803. goto alloc_err;
  804. } else
  805. pr_info("%s : isdbt-detect-gpio gpio_int =%d\n", __func__, pdata->gpio_int);
  806. pdata->gpio_spi_do = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-spi_do", 0);
  807. if (pdata->gpio_spi_do < 0) {
  808. pr_err("%s : can not find the isdbt-detect-gpio in the gpio_spi_do dt\n", __func__);
  809. goto alloc_err;
  810. } else
  811. pr_info("%s : isdbt-detect-gpio gpio_spi_do =%d\n", __func__, pdata->gpio_spi_do);
  812. pdata->gpio_spi_di = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-spi_di", 0);
  813. if (pdata->gpio_spi_di < 0) {
  814. pr_err("%s : can not find the isdbt-detect-gpio in the gpio_spi_di dt\n", __func__);
  815. goto alloc_err;
  816. } else
  817. pr_info("%s : isdbt-detect-gpio gpio_spi_di =%d\n", __func__, pdata->gpio_spi_di);
  818. pdata->gpio_spi_cs = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-spi_cs", 0);
  819. if (pdata->gpio_spi_cs < 0) {
  820. pr_err("%s : can not find the isdbt-detect-gpio gpio_spi_cs in the dt\n", __func__);
  821. goto alloc_err;
  822. } else
  823. pr_info("%s : isdbt-detect-gpio gpio_spi_cs=%d\n", __func__, pdata->gpio_spi_cs);
  824. pdata->gpio_spi_clk = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-spi_clk", 0);
  825. if (pdata->gpio_spi_clk < 0) {
  826. pr_err("%s : can not find the isdbt-detect-gpio gpio_spi_clk in the dt\n", __func__);
  827. goto alloc_err;
  828. } else
  829. pr_info("%s : isdbt-detect-gpio gpio_spi_clk=%d\n", __func__, pdata->gpio_spi_clk);
  830. return pdata;
  831. alloc_err:
  832. devm_kfree(dev, pdata);
  833. err:
  834. return NULL;
  835. }
  836. static int isdbt_probe(struct platform_device *pdev)
  837. {
  838. int res;
  839. printk("%s\n", __func__);
  840. isdbt_pdata = isdbt_populate_dt_pdata(&pdev->dev);
  841. if (!isdbt_pdata) {
  842. pr_err("%s : isdbt_pdata is NULL.\n", __func__);
  843. return -ENODEV;
  844. }
  845. isdbt_gpio_init();
  846. res = misc_register(&fc8150_misc_device);
  847. if (res < 0) {
  848. PRINTF(hInit, "isdbt init fail : %d\n", res);
  849. return res;
  850. }
  851. res = request_irq(gpio_to_irq(isdbt_pdata->gpio_int), isdbt_irq
  852. , IRQF_DISABLED | IRQF_TRIGGER_RISING, FC8150_NAME, NULL);
  853. if (res < 0) {
  854. printk("isdbt_probe: couldn't request gpio");
  855. return res;
  856. }
  857. hInit = kmalloc(sizeof(struct ISDBT_INIT_INFO_T), GFP_KERNEL);
  858. res = BBM_HOSTIF_SELECT(hInit, BBM_SPI);
  859. if (res)
  860. PRINTF(hInit, "isdbt host interface select fail!\n");
  861. isdbt_hw_stop();
  862. if (!isdbt_kthread) {
  863. PRINTF(hInit, "isdb kthread run\n");
  864. isdbt_kthread = kthread_run(isdbt_thread
  865. , (void *)hInit, "isdbt_thread");
  866. }
  867. INIT_LIST_HEAD(&(hInit->hHead));
  868. #if defined(CONFIG_ISDBT_ANT_DET)
  869. wake_lock_init(&isdbt_ant_wlock, WAKE_LOCK_SUSPEND, "isdbt_ant_wlock");
  870. if (!isdbt_ant_det_reg_input(pdev))
  871. goto err_reg_input;
  872. if (!isdbt_ant_det_create_wq())
  873. goto free_reg_input;
  874. if (!isdbt_ant_det_irq_set(true))
  875. goto free_ant_det_wq;
  876. return 0;
  877. free_ant_det_wq:
  878. isdbt_ant_det_destroy_wq();
  879. free_reg_input:
  880. isdbt_ant_det_unreg_input();
  881. err_reg_input:
  882. return -EFAULT;
  883. #else
  884. return 0;
  885. #endif
  886. }
  887. static int isdbt_remove(struct platform_device *pdev)
  888. {
  889. printk("ISDBT remove\n");
  890. #if defined(CONFIG_ISDBT_ANT_DET)
  891. isdbt_ant_det_unreg_input();
  892. isdbt_ant_det_destroy_wq();
  893. isdbt_ant_det_irq_set(false);
  894. wake_lock_destroy(&isdbt_ant_wlock);
  895. #endif
  896. return 0;
  897. }
  898. static int isdbt_suspend(struct platform_device *pdev, pm_message_t mesg)
  899. {
  900. int value;
  901. #ifdef CONFIG_ISDBT_SPMI
  902. u8 reg = 0x00;
  903. printk("%s, Tuning ISDBT_CLK off\n", __func__);
  904. printk("%s Writing 0x00 to register 0x%x\n", __func__, spmi_addr);
  905. if(isdbt_spmi)
  906. {
  907. int rc = spmi_ext_register_writel(isdbt_spmi->spmi->ctrl, isdbt_spmi->spmi->sid, spmi_addr,&reg, 1);
  908. if (rc) {
  909. printk("%s, Unable to write from addr=%x, rc(%d)\n", __func__, spmi_addr, rc );
  910. }
  911. }
  912. else
  913. printk("%s ERROR !! isdbt_spmi is NULL !!\n", __func__);
  914. #endif
  915. value = gpio_get_value_cansleep(isdbt_pdata->gpio_en);
  916. printk("%s value = %d\n",__func__,value);
  917. if(value == 1)
  918. {
  919. gpio_set_value(isdbt_pdata->gpio_en, 0);
  920. }
  921. return 0;
  922. }
  923. static int isdbt_resume(struct platform_device *pdev)
  924. {
  925. return 0;
  926. }
  927. static const struct of_device_id isdbt_match_table[] = {
  928. {
  929. #ifdef CONFIG_ISDBT_FC8150_HKDI
  930. .compatible = "isdb_pdata",
  931. #else
  932. .compatible = "isdb_fc8300_pdata",
  933. #endif
  934. },
  935. {}
  936. };
  937. static struct platform_driver isdbt_driver = {
  938. .driver = {
  939. .owner = THIS_MODULE,
  940. .name = "isdbt",
  941. .of_match_table = isdbt_match_table,
  942. },
  943. .probe = isdbt_probe,
  944. .remove = isdbt_remove,
  945. .suspend = isdbt_suspend,
  946. .resume = isdbt_resume,
  947. };
  948. int isdbt_init(void)
  949. {
  950. s32 res;
  951. PRINTF(hInit, "isdbt_init\n");
  952. #ifdef CONFIG_ISDBT_SPMI
  953. res = spmi_driver_register(&qpnp_isdbt_clk_driver);
  954. if(res < 0){
  955. printk("Error : qpnp isdbt clk init fail : %d\n", res);
  956. }
  957. printk("qpnp isdbt clk init done \n");
  958. #endif
  959. res = platform_driver_register(&isdbt_driver);
  960. if (res < 0) {
  961. PRINTF(hInit, "isdbt init fail : %d\n", res);
  962. return res;
  963. }
  964. return 0;
  965. }
  966. void isdbt_exit(void)
  967. {
  968. PRINTF(hInit, "isdbt isdbt_exit\n");
  969. free_irq(gpio_to_irq(isdbt_pdata->gpio_int), NULL);
  970. gpio_free(isdbt_pdata->gpio_int);
  971. gpio_free(isdbt_pdata->gpio_rst);
  972. gpio_free(isdbt_pdata->gpio_en);
  973. kthread_stop(isdbt_kthread);
  974. isdbt_kthread = NULL;
  975. BBM_HOSTIF_DESELECT(hInit);
  976. isdbt_hw_deinit();
  977. platform_driver_unregister(&isdbt_driver);
  978. misc_deregister(&fc8150_misc_device);
  979. kfree(hInit);
  980. #ifdef CONFIG_ISDBT_SPMI
  981. spmi_driver_unregister(&qpnp_isdbt_clk_driver);
  982. #endif
  983. }
  984. module_init(isdbt_init);
  985. module_exit(isdbt_exit);
  986. MODULE_LICENSE("Dual BSD/GPL");