fc8150.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  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/io.h>
  12. #include <mach/isdbt_tuner_pdata.h>
  13. #include <mach/gpio.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/wakelock.h>
  16. #include <linux/input.h>
  17. #include <mach/gpiomux.h>
  18. #include <linux/of_gpio.h>
  19. #include "fc8150.h"
  20. #include "bbm.h"
  21. #include "fci_oal.h"
  22. #include "fci_tun.h"
  23. #include "fc8150_regs.h"
  24. #include "fc8150_isr.h"
  25. #include "fci_hal.h"
  26. #include "fc8150_i2c.h"
  27. #include <asm/system_info.h>
  28. struct ISDBT_INIT_INFO_T *hInit;
  29. #define RING_BUFFER_SIZE (128 * 1024) /* kmalloc max 128k */
  30. /* GPIO(RESET & INTRRUPT) Setting */
  31. #define FC8150_NAME "isdbt"
  32. static struct isdbt_platform_data *isdbt_pdata;
  33. enum ISDBT_MODE driver_mode = ISDBT_POWEROFF;
  34. static DEFINE_MUTEX(ringbuffer_lock);
  35. static DECLARE_WAIT_QUEUE_HEAD(isdbt_isr_wait);
  36. #ifndef BBM_I2C_TSIF
  37. static u8 isdbt_isr_sig;
  38. static struct task_struct *isdbt_kthread;
  39. static irqreturn_t isdbt_irq(int irq, void *dev_id)
  40. {
  41. isdbt_isr_sig = 1;
  42. wake_up_interruptible(&isdbt_isr_wait);
  43. return IRQ_HANDLED;
  44. }
  45. #endif
  46. int isdbt_hw_setting(void)
  47. {
  48. int err;
  49. PRINTF(0, "isdbt_hw_setting \n");
  50. err = gpio_request(isdbt_pdata->gpio_en, "isdbt_en");
  51. if (err) {
  52. PRINTF(0, "isdbt_hw_setting: Couldn't request isdbt_en\n");
  53. goto ISBT_EN_ERR;
  54. }
  55. gpio_direction_output(isdbt_pdata->gpio_en, 0);
  56. err = gpio_request(isdbt_pdata->gpio_rst, "isdbt_rst");
  57. if (err) {
  58. PRINTF(0, "isdbt_hw_setting: Couldn't request isdbt_rst\n");
  59. goto ISDBT_RST_ERR;
  60. }
  61. gpio_direction_output(isdbt_pdata->gpio_rst, 1);
  62. err = gpio_request(isdbt_pdata->gpio_int, "isdbt_irq");
  63. if (err) {
  64. PRINTF(0, "isdbt_hw_setting: Couldn't request isdbt_irq\n");
  65. goto ISDBT_INT_ERR;
  66. }
  67. #ifndef BBM_I2C_TSIF
  68. gpio_direction_input(isdbt_pdata->gpio_int);
  69. err = request_irq(gpio_to_irq(isdbt_pdata->gpio_int), isdbt_irq
  70. , IRQF_DISABLED | IRQF_TRIGGER_RISING, FC8150_NAME, NULL);
  71. if (err < 0) {
  72. PRINTF(0,
  73. "isdbt_hw_setting: couldn't request gpio \
  74. interrupt %d reason(%d)\n"
  75. , gpio_to_irq(isdbt_pdata->gpio_int), err);
  76. goto request_isdbt_irq;
  77. }
  78. err = gpio_request(isdbt_pdata->gpio_i2c_sda, "isdbt_i2c_sda");
  79. if (err) {
  80. pr_err("isdbt_hw_setting: Couldn't request gpio_i2c_sda\n");
  81. //goto ISDBT_INT_ERR;
  82. err = 0;
  83. }
  84. //gpio_free(isdbt_pdata->gpio_i2c_sda);
  85. err = gpio_request(isdbt_pdata->gpio_i2c_scl, "isdbt_i2c_scl");
  86. if (err) {
  87. pr_err("isdbt_hw_setting: Couldn't request gpio_i2c_scl\n");
  88. // goto ISDBT_INT_ERR;
  89. err = 0;
  90. }
  91. //gpio_free(isdbt_pdata->gpio_i2c_scl);
  92. #endif
  93. return 0;
  94. #ifndef BBM_I2C_TSIF
  95. request_isdbt_irq:
  96. gpio_free(isdbt_pdata->gpio_int);
  97. #endif
  98. ISDBT_INT_ERR:
  99. gpio_free(isdbt_pdata->gpio_rst);
  100. ISDBT_RST_ERR:
  101. gpio_free(isdbt_pdata->gpio_en);
  102. ISBT_EN_ERR:
  103. return err;
  104. }
  105. static void isdbt_gpio_init(void)
  106. {
  107. pr_err("%s\n",__func__);
  108. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_en, GPIOMUX_FUNC_GPIO,
  109. GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
  110. GPIO_CFG_ENABLE);
  111. //gpio_set_value(isdbt_pdata->gpio_en, 0);
  112. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_rst, GPIOMUX_FUNC_GPIO,
  113. GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
  114. GPIO_CFG_ENABLE);
  115. //gpio_set_value(isdbt_pdata->gpio_rst, 0);
  116. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_int, GPIOMUX_FUNC_GPIO,
  117. GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
  118. GPIO_CFG_ENABLE);
  119. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_i2c_sda, GPIOMUX_FUNC_3,
  120. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
  121. GPIO_CFG_ENABLE);
  122. gpio_tlmm_config(GPIO_CFG(isdbt_pdata->gpio_i2c_scl, GPIOMUX_FUNC_3,
  123. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
  124. GPIO_CFG_ENABLE);
  125. isdbt_hw_setting();
  126. }
  127. /*POWER_ON & HW_RESET & INTERRUPT_CLEAR */
  128. void isdbt_hw_init(void)
  129. {
  130. int i = 0;
  131. while (driver_mode == ISDBT_DATAREAD) {
  132. msWait(100);
  133. if (i++ > 5)
  134. break;
  135. }
  136. PRINTF(0, "isdbt_hw_init \n");
  137. gpio_set_value(isdbt_pdata->gpio_en, 1);
  138. gpio_set_value(isdbt_pdata->gpio_rst, 1);
  139. mdelay(5);
  140. gpio_set_value(isdbt_pdata->gpio_rst, 0);
  141. mdelay(1);
  142. gpio_set_value(isdbt_pdata->gpio_rst, 1);
  143. driver_mode = ISDBT_POWERON;
  144. }
  145. /*POWER_OFF */
  146. void isdbt_hw_deinit(void)
  147. {
  148. PRINTF(0, "isdbt_hw_deinit \n");
  149. driver_mode = ISDBT_POWEROFF;
  150. gpio_set_value(isdbt_pdata->gpio_en, 0);
  151. gpio_set_value(isdbt_pdata->gpio_rst, 0);
  152. }
  153. int data_callback(u32 hDevice, u8 *data, int len)
  154. {
  155. struct ISDBT_INIT_INFO_T *hInit;
  156. struct list_head *temp;
  157. hInit = (struct ISDBT_INIT_INFO_T *)hDevice;
  158. list_for_each(temp, &(hInit->hHead))
  159. {
  160. struct ISDBT_OPEN_INFO_T *hOpen;
  161. hOpen = list_entry(temp, struct ISDBT_OPEN_INFO_T, hList);
  162. if (hOpen->isdbttype == TS_TYPE) {
  163. mutex_lock(&ringbuffer_lock);
  164. if (fci_ringbuffer_free(&hOpen->RingBuffer) < len) {
  165. /*PRINTF(hDevice, "f"); */
  166. /* return 0 */;
  167. FCI_RINGBUFFER_SKIP(&hOpen->RingBuffer, len);
  168. }
  169. fci_ringbuffer_write(&hOpen->RingBuffer, data, len);
  170. wake_up_interruptible(&(hOpen->RingBuffer.queue));
  171. mutex_unlock(&ringbuffer_lock);
  172. }
  173. }
  174. return 0;
  175. }
  176. #ifndef BBM_I2C_TSIF
  177. static int isdbt_thread(void *hDevice)
  178. {
  179. struct ISDBT_INIT_INFO_T *hInit = (struct ISDBT_INIT_INFO_T *)hDevice;
  180. set_user_nice(current, -20);
  181. PRINTF(hInit, "isdbt_kthread enter\n");
  182. BBM_TS_CALLBACK_REGISTER((u32)hInit, data_callback);
  183. while (1) {
  184. wait_event_interruptible(isdbt_isr_wait,
  185. isdbt_isr_sig || kthread_should_stop());
  186. if (driver_mode == ISDBT_POWERON) {
  187. driver_mode = ISDBT_DATAREAD;
  188. BBM_ISR(hInit);
  189. driver_mode = ISDBT_POWERON;
  190. }
  191. isdbt_isr_sig = 0;
  192. if (kthread_should_stop())
  193. break;
  194. }
  195. BBM_TS_CALLBACK_DEREGISTER();
  196. PRINTF(hInit, "isdbt_kthread exit\n");
  197. return 0;
  198. }
  199. #endif
  200. const struct file_operations isdbt_fops = {
  201. .owner = THIS_MODULE,
  202. .unlocked_ioctl = isdbt_ioctl,
  203. .open = isdbt_open,
  204. .read = isdbt_read,
  205. .release = isdbt_release,
  206. };
  207. static struct miscdevice fc8150_misc_device = {
  208. .minor = MISC_DYNAMIC_MINOR,
  209. .name = FC8150_NAME,
  210. .fops = &isdbt_fops,
  211. };
  212. int isdbt_open(struct inode *inode, struct file *filp)
  213. {
  214. struct ISDBT_OPEN_INFO_T *hOpen;
  215. PRINTF(hInit, "isdbt open\n");
  216. hOpen = kmalloc(sizeof(struct ISDBT_OPEN_INFO_T), GFP_KERNEL);
  217. hOpen->buf = kmalloc(RING_BUFFER_SIZE, GFP_KERNEL);
  218. hOpen->isdbttype = 0;
  219. list_add(&(hOpen->hList), &(hInit->hHead));
  220. hOpen->hInit = (HANDLE *)hInit;
  221. if (hOpen->buf == NULL) {
  222. PRINTF(hInit, "ring buffer malloc error\n");
  223. return -ENOMEM;
  224. }
  225. fci_ringbuffer_init(&hOpen->RingBuffer, hOpen->buf, RING_BUFFER_SIZE);
  226. filp->private_data = hOpen;
  227. return 0;
  228. }
  229. ssize_t isdbt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
  230. {
  231. s32 avail;
  232. s32 non_blocking = filp->f_flags & O_NONBLOCK;
  233. struct ISDBT_OPEN_INFO_T *hOpen
  234. = (struct ISDBT_OPEN_INFO_T *)filp->private_data;
  235. struct fci_ringbuffer *cibuf = &hOpen->RingBuffer;
  236. ssize_t len, read_len = 0;
  237. if (!cibuf->data || !count) {
  238. /*PRINTF(hInit, " return 0\n"); */
  239. return 0;
  240. }
  241. if (non_blocking && (fci_ringbuffer_empty(cibuf))) {
  242. /*PRINTF(hInit, "return EWOULDBLOCK\n"); */
  243. return -EWOULDBLOCK;
  244. }
  245. if (wait_event_interruptible(cibuf->queue,
  246. !fci_ringbuffer_empty(cibuf))) {
  247. PRINTF(hInit, "return ERESTARTSYS\n");
  248. return -ERESTARTSYS;
  249. }
  250. mutex_lock(&ringbuffer_lock);
  251. avail = fci_ringbuffer_avail(cibuf);
  252. if (count >= avail)
  253. len = avail;
  254. else
  255. len = count - (count % 188);
  256. read_len = fci_ringbuffer_read_user(cibuf, buf, len);
  257. mutex_unlock(&ringbuffer_lock);
  258. return read_len;
  259. }
  260. int isdbt_release(struct inode *inode, struct file *filp)
  261. {
  262. struct ISDBT_OPEN_INFO_T *hOpen;
  263. PRINTF(hInit, "isdbt_release\n");
  264. hOpen = filp->private_data;
  265. hOpen->isdbttype = 0;
  266. list_del(&(hOpen->hList));
  267. kfree(hOpen->buf);
  268. kfree(hOpen);
  269. return 0;
  270. }
  271. int fc8150_if_test(void)
  272. {
  273. int res = 0;
  274. int i;
  275. u16 wdata = 0;
  276. u32 ldata = 0;
  277. u8 data = 0;
  278. u8 temp = 0;
  279. PRINTF(0, "fc8150_if_test Start!!!\n");
  280. for (i = 0 ; i < 100 ; i++) {
  281. BBM_BYTE_WRITE(0, 0xa4, i & 0xff);
  282. BBM_BYTE_READ(0, 0xa4, &data);
  283. if ((i & 0xff) != data) {
  284. PRINTF(0, "fc8150_if_btest! i=0x%x, data=0x%x\n"
  285. , i & 0xff, data);
  286. res = 1;
  287. }
  288. }
  289. for (i = 0 ; i < 100 ; i++) {
  290. BBM_WORD_WRITE(0, 0xa4, i & 0xffff);
  291. BBM_WORD_READ(0, 0xa4, &wdata);
  292. if ((i & 0xffff) != wdata) {
  293. PRINTF(0, "fc8150_if_wtest! i=0x%x, data=0x%x\n"
  294. , i & 0xffff, wdata);
  295. res = 1;
  296. }
  297. }
  298. for (i = 0 ; i < 100 ; i++) {
  299. BBM_LONG_WRITE(0, 0xa4, i & 0xffffffff);
  300. BBM_LONG_READ(0, 0xa4, &ldata);
  301. if ((i & 0xffffffff) != ldata) {
  302. PRINTF(0, "fc8150_if_ltest! i=0x%x, data=0x%x\n"
  303. , i & 0xffffffff, ldata);
  304. res = 1;
  305. }
  306. }
  307. for (i = 0 ; i < 100 ; i++) {
  308. temp = i & 0xff;
  309. BBM_TUNER_WRITE(NULL, 0x52, 0x01, &temp, 0x01);
  310. BBM_TUNER_READ(NULL, 0x52, 0x01, &data, 0x01);
  311. if ((i & 0xff) != data)
  312. PRINTF(0, "FC8150 tuner test (0x%x,0x%x)\n"
  313. , i & 0xff, data);
  314. }
  315. PRINTF(0, "fc8150_if_test End!!!\n");
  316. return res;
  317. }
  318. #ifndef BBM_I2C_TSIF
  319. void isdbt_isr_check(HANDLE hDevice)
  320. {
  321. u8 isr_time = 0;
  322. BBM_WRITE(hDevice, BBM_BUF_INT, 0x00);
  323. while (isr_time < 10) {
  324. if (!isdbt_isr_sig)
  325. break;
  326. msWait(10);
  327. isr_time++;
  328. }
  329. }
  330. #endif
  331. long isdbt_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  332. {
  333. s32 res = BBM_NOK;
  334. s32 err = 0;
  335. s32 size = 0;
  336. struct ISDBT_OPEN_INFO_T *hOpen;
  337. struct ioctl_info info;
  338. if (_IOC_TYPE(cmd) != IOCTL_MAGIC)
  339. return -EINVAL;
  340. if (_IOC_NR(cmd) >= IOCTL_MAXNR)
  341. return -EINVAL;
  342. hOpen = filp->private_data;
  343. size = _IOC_SIZE(cmd);
  344. switch (cmd) {
  345. case IOCTL_ISDBT_RESET:
  346. res = BBM_RESET(hInit);
  347. break;
  348. case IOCTL_ISDBT_INIT:
  349. #ifdef BBM_I2C_TSIF
  350. res = BBM_I2C_INIT(hInit, FCI_BYPASS_TYPE);
  351. #else
  352. res = BBM_I2C_INIT(hInit, FCI_I2C_TYPE);
  353. #endif
  354. res |= BBM_PROBE(hInit);
  355. if (res) {
  356. PRINTF(hInit, "FC8150 Initialize Fail \n");
  357. break;
  358. }
  359. res |= BBM_INIT(hInit);
  360. break;
  361. case IOCTL_ISDBT_BYTE_READ:
  362. err = copy_from_user((void *)&info, (void *)arg, size);
  363. res = BBM_BYTE_READ(hInit, (u16)info.buff[0]
  364. , (u8 *)(&info.buff[1]));
  365. err |= copy_to_user((void *)arg, (void *)&info, size);
  366. break;
  367. case IOCTL_ISDBT_WORD_READ:
  368. err = copy_from_user((void *)&info, (void *)arg, size);
  369. res = BBM_WORD_READ(hInit, (u16)info.buff[0]
  370. , (u16 *)(&info.buff[1]));
  371. err |= copy_to_user((void *)arg, (void *)&info, size);
  372. break;
  373. case IOCTL_ISDBT_LONG_READ:
  374. err = copy_from_user((void *)&info, (void *)arg, size);
  375. res = BBM_LONG_READ(hInit, (u16)info.buff[0]
  376. , (u32 *)(&info.buff[1]));
  377. err |= copy_to_user((void *)arg, (void *)&info, size);
  378. break;
  379. case IOCTL_ISDBT_BULK_READ:
  380. err = copy_from_user((void *)&info, (void *)arg, size);
  381. res = BBM_BULK_READ(hInit, (u16)info.buff[0]
  382. , (u8 *)(&info.buff[2]), info.buff[1]);
  383. err |= copy_to_user((void *)arg, (void *)&info, size);
  384. break;
  385. case IOCTL_ISDBT_BYTE_WRITE:
  386. err = copy_from_user((void *)&info, (void *)arg, size);
  387. res = BBM_BYTE_WRITE(hInit, (u16)info.buff[0]
  388. , (u8)info.buff[1]);
  389. break;
  390. case IOCTL_ISDBT_WORD_WRITE:
  391. err = copy_from_user((void *)&info, (void *)arg, size);
  392. res = BBM_WORD_WRITE(hInit, (u16)info.buff[0]
  393. , (u16)info.buff[1]);
  394. break;
  395. case IOCTL_ISDBT_LONG_WRITE:
  396. err = copy_from_user((void *)&info, (void *)arg, size);
  397. res = BBM_LONG_WRITE(hInit, (u16)info.buff[0]
  398. , (u32)info.buff[1]);
  399. break;
  400. case IOCTL_ISDBT_BULK_WRITE:
  401. err = copy_from_user((void *)&info, (void *)arg, size);
  402. res = BBM_BULK_WRITE(hInit, (u16)info.buff[0]
  403. , (u8 *)(&info.buff[2]), info.buff[1]);
  404. break;
  405. case IOCTL_ISDBT_TUNER_READ:
  406. err = copy_from_user((void *)&info, (void *)arg, size);
  407. res = BBM_TUNER_READ(hInit, (u8)info.buff[0]
  408. , (u8)info.buff[1], (u8 *)(&info.buff[3])
  409. , (u8)info.buff[2]);
  410. err |= copy_to_user((void *)arg, (void *)&info, size);
  411. break;
  412. case IOCTL_ISDBT_TUNER_WRITE:
  413. err = copy_from_user((void *)&info, (void *)arg, size);
  414. res = BBM_TUNER_WRITE(hInit, (u8)info.buff[0]
  415. , (u8)info.buff[1], (u8 *)(&info.buff[3])
  416. , (u8)info.buff[2]);
  417. break;
  418. case IOCTL_ISDBT_TUNER_SET_FREQ:
  419. {
  420. u32 f_rf;
  421. PRINTF(hInit, "IOCTL_ISDBT_TUNER_SET_FREQ\n");
  422. err = copy_from_user((void *)&info, (void *)arg, size);
  423. f_rf = ((u32)info.buff[0] - 13) * 6000 + 473143;
  424. #ifndef BBM_I2C_TSIF
  425. isdbt_isr_check(hInit);
  426. #endif
  427. res = BBM_TUNER_SET_FREQ(hInit, f_rf);
  428. #ifndef BBM_I2C_TSIF
  429. mutex_lock(&ringbuffer_lock);
  430. fci_ringbuffer_flush(&hOpen->RingBuffer);
  431. mutex_unlock(&ringbuffer_lock);
  432. BBM_WRITE(hInit, BBM_BUF_INT, 0x01);
  433. #endif
  434. }
  435. break;
  436. case IOCTL_ISDBT_TUNER_SELECT:
  437. PRINTF(hInit, "IOCTL_ISDBT_TUNER_SELECT\n");
  438. err = copy_from_user((void *)&info, (void *)arg, size);
  439. res = BBM_TUNER_SELECT(hInit, (u32)info.buff[0], 0);
  440. break;
  441. case IOCTL_ISDBT_TS_START:
  442. PRINTF(hInit, "IOCTL_ISDBT_TS_START\n");
  443. hOpen->isdbttype = TS_TYPE;
  444. break;
  445. case IOCTL_ISDBT_TS_STOP:
  446. PRINTF(hInit, "IOCTL_ISDBT_TS_STOP\n");
  447. hOpen->isdbttype = 0;
  448. break;
  449. case IOCTL_ISDBT_POWER_ON:
  450. PRINTF(hInit, "IOCTL_ISDBT_POWER_ON\n");
  451. isdbt_hw_init();
  452. break;
  453. case IOCTL_ISDBT_POWER_OFF:
  454. PRINTF(hInit, "IOCTL_ISDBT_POWER_OFF\n");
  455. isdbt_hw_deinit();
  456. break;
  457. case IOCTL_ISDBT_SCAN_STATUS:
  458. res = BBM_SCAN_STATUS(hInit);
  459. break;
  460. case IOCTL_ISDBT_TUNER_GET_RSSI:
  461. err = copy_from_user((void *)&info, (void *)arg, size);
  462. res = BBM_TUNER_GET_RSSI(hInit, (s32 *)&info.buff[0]);
  463. err |= copy_to_user((void *)arg, (void *)&info, size);
  464. break;
  465. default:
  466. PRINTF(hInit, "isdbt ioctl error!\n");
  467. res = BBM_NOK;
  468. break;
  469. }
  470. if (err < 0) {
  471. PRINTF(hInit, "copy to/from user fail : %d", err);
  472. res = BBM_NOK;
  473. }
  474. return res;
  475. }
  476. static struct isdbt_platform_data *isdbt_populate_dt_pdata(struct device *dev)
  477. {
  478. struct isdbt_platform_data *pdata;
  479. pr_err("%s\n", __func__);
  480. pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
  481. if (!pdata) {
  482. pr_err("%s : could not allocate memory for platform data\n", __func__);
  483. goto err;
  484. }
  485. pdata->gpio_en = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-pwr-en", 0);
  486. if (pdata->gpio_en < 0) {
  487. pr_err("%s : can not find the isdbt-detect-gpio gpio_en in the dt\n", __func__);
  488. goto alloc_err;
  489. } else
  490. pr_err("%s : isdbt-detect-gpio gpio_en =%d\n", __func__, pdata->gpio_en);
  491. pdata->gpio_rst = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-rst", 0);
  492. if (pdata->gpio_rst < 0) {
  493. pr_err("%s : can not find the isdbt-detect-gpio gpio_rst in the dt\n", __func__);
  494. goto alloc_err;
  495. } else
  496. pr_err("%s : isdbt-detect-gpio gpio_rst =%d\n", __func__, pdata->gpio_rst);
  497. pdata->gpio_int = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-irq", 0);
  498. if (pdata->gpio_int < 0) {
  499. pr_err("%s : can not find the isdbt-detect-gpio in the gpio_int dt\n", __func__);
  500. goto alloc_err;
  501. } else
  502. pr_err("%s : isdbt-detect-gpio gpio_int =%d\n", __func__, pdata->gpio_int);
  503. pdata->gpio_i2c_sda = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-i2c_sda", 0);
  504. if (pdata->gpio_i2c_sda < 0) {
  505. pr_err("%s : can not find the isdbt-detect-gpio gpio_i2c_sda in the dt\n", __func__);
  506. goto alloc_err;
  507. } else
  508. pr_err("%s : isdbt-detect-gpio gpio_i2c_sda=%d\n", __func__, pdata->gpio_i2c_sda);
  509. pdata->gpio_i2c_scl = of_get_named_gpio(dev->of_node, "qcom,isdb-gpio-i2c_scl", 0);
  510. if (pdata->gpio_i2c_scl < 0) {
  511. pr_err("%s : can not find the isdbt-detect-gpio gpio_i2c_scl in the dt\n", __func__);
  512. goto alloc_err;
  513. } else
  514. pr_err("%s : isdbt-detect-gpio gpio_i2c_scl=%d\n", __func__, pdata->gpio_i2c_scl);
  515. return pdata;
  516. alloc_err:
  517. devm_kfree(dev, pdata);
  518. err:
  519. return NULL;
  520. }
  521. static int isdbt_probe(struct platform_device *pdev)
  522. {
  523. s32 res;
  524. pr_err("%s\n", __func__);
  525. isdbt_pdata = isdbt_populate_dt_pdata(&pdev->dev);
  526. if (!isdbt_pdata) {
  527. pr_err("%s : isdbt_pdata is NULL.\n", __func__);
  528. return -ENODEV;
  529. }
  530. isdbt_gpio_init();
  531. res = misc_register(&fc8150_misc_device);
  532. if (res < 0) {
  533. PRINTF(hInit, "isdbt init fail : %d\n", res);
  534. return res;
  535. }
  536. hInit = kmalloc(sizeof(struct ISDBT_INIT_INFO_T), GFP_KERNEL);
  537. #ifdef BBM_I2C_TSIF
  538. res = BBM_HOSTIF_SELECT(hInit, BBM_I2C);
  539. //mdelay(1000);
  540. //fc8150_tsif_setting(hInit); //shubham
  541. #else
  542. res = BBM_HOSTIF_SELECT(hInit, BBM_SPI);
  543. #endif
  544. if (res)
  545. PRINTF(hInit, "isdbt host interface select fail!\n");
  546. #ifndef BBM_I2C_TSIF
  547. if (!isdbt_kthread) {
  548. PRINTF(hInit, "kthread run\n");
  549. isdbt_kthread = kthread_run(isdbt_thread
  550. , (void *)hInit, "isdbt_thread");
  551. }
  552. #endif
  553. INIT_LIST_HEAD(&(hInit->hHead));
  554. return 0;
  555. }
  556. static int isdbt_remove(struct platform_device *pdev)
  557. {
  558. pr_err("ISDBT remove\n");
  559. return 0;
  560. }
  561. static int isdbt_suspend(struct platform_device *pdev, pm_message_t mesg)
  562. {
  563. int value;
  564. value = gpio_get_value_cansleep(isdbt_pdata->gpio_en);
  565. pr_err("%s value = %d\n",__func__,value);
  566. if(value == 1)
  567. {
  568. gpio_set_value(isdbt_pdata->gpio_en, 0);
  569. }
  570. return 0;
  571. }
  572. static int isdbt_resume(struct platform_device *pdev)
  573. {
  574. return 0;
  575. }
  576. static const struct of_device_id isdbt_match_table[] = {
  577. { .compatible = "isdb_fc8300_pdata",
  578. },
  579. {}
  580. };
  581. static struct platform_driver isdb_fc8150_driver = {
  582. .driver = {
  583. .owner = THIS_MODULE,
  584. .name = "isdbt",
  585. .of_match_table = isdbt_match_table,
  586. },
  587. .probe = isdbt_probe,
  588. .remove = isdbt_remove,
  589. .suspend = isdbt_suspend,
  590. .resume = isdbt_resume,
  591. };
  592. int isdbt_init(void)
  593. {
  594. s32 res;
  595. pr_err("isdbt_fc8150_init started\n");
  596. res = platform_driver_register(&isdb_fc8150_driver);
  597. if (res < 0) {
  598. pr_err("isdbt init fail : %d\n", res);
  599. return res;
  600. }
  601. return 0;
  602. }
  603. void isdbt_exit(void)
  604. {
  605. PRINTF(hInit, "isdbt isdbt_exit \n");
  606. free_irq(gpio_to_irq(isdbt_pdata->gpio_int), NULL);
  607. #ifndef BBM_I2C_TSIF
  608. gpio_free(isdbt_pdata->gpio_int);
  609. #endif
  610. gpio_free(isdbt_pdata->gpio_rst);
  611. gpio_free(isdbt_pdata->gpio_en);
  612. gpio_free(isdbt_pdata->gpio_i2c_sda);
  613. gpio_free(isdbt_pdata->gpio_i2c_scl);
  614. #ifndef BBM_I2C_TSIF
  615. if (isdbt_kthread)
  616. kthread_stop(isdbt_kthread);
  617. isdbt_kthread = NULL;
  618. #endif
  619. BBM_HOSTIF_DESELECT(hInit);
  620. isdbt_hw_deinit();
  621. platform_driver_unregister(&isdb_fc8150_driver);
  622. misc_deregister(&fc8150_misc_device);
  623. kfree(hInit);
  624. }
  625. module_init(isdbt_init);
  626. module_exit(isdbt_exit);
  627. MODULE_LICENSE("Dual BSD/GPL");