tuner_drv.c 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667
  1. /*
  2. *
  3. * drivers/media/isdbtmm/tuner_drv.c
  4. *
  5. * MM Tuner Driver
  6. *
  7. * Copyright (C) (2013, Samsung Electronics)
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation version 2.
  12. *
  13. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  14. * kind, whether express or implied; without even the implied warranty
  15. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. */
  19. /******************************************************************************
  20. * include
  21. ******************************************************************************/
  22. #include <linux/module.h>
  23. #include <linux/kernel.h>
  24. #include <linux/init.h>
  25. #include <linux/types.h>
  26. #include <linux/fs.h>
  27. #include <linux/cdev.h>
  28. #include <linux/sched.h>
  29. #include <linux/platform_device.h>
  30. #include <linux/device.h>
  31. #include <linux/poll.h>
  32. #include <linux/interrupt.h>
  33. #include <linux/err.h>
  34. #include <linux/slab.h>
  35. #include <linux/i2c.h>
  36. #include <linux/i2c-dev.h>
  37. #include <asm/uaccess.h>
  38. #include <asm/irq.h>
  39. #include <linux/mm.h>
  40. #include <linux/vmalloc.h>
  41. #include <linux/kthread.h>
  42. #include <linux/version.h>
  43. #include <mach/isdbtmm_pdata.h>
  44. #include <mach/gpiomux.h>
  45. #include <linux/of_gpio.h>
  46. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  47. #include <linux/mutex.h>
  48. #endif
  49. #include "tuner_drv.h"
  50. #include "tuner.h"
  51. #if defined(CONFIG_TMM_ANT_DET)
  52. /* for delay(sleep) */
  53. #include <linux/delay.h>
  54. /* for mutex */
  55. #include <linux/mutex.h>
  56. /*using copy to user */
  57. #include <linux/uaccess.h>
  58. #include <linux/clk.h>
  59. #include <linux/workqueue.h>
  60. #include <linux/irq.h>
  61. #include <asm/mach/irq.h>
  62. #include <linux/io.h>
  63. #include <linux/gpio.h>
  64. #include <linux/wakelock.h>
  65. #include <linux/input.h>
  66. #endif
  67. /******************************************************************************
  68. * data
  69. ******************************************************************************/
  70. /* Mmap Address */
  71. void *mem_p;
  72. /* poll control */
  73. wait_queue_head_t g_tuner_poll_wait_queue; /* poll queue */
  74. spinlock_t g_tuner_lock; /* spin lock */
  75. unsigned long g_tuner_wakeup_flag; /* poll wait flag */
  76. /* interrupt factor */
  77. unsigned char g_tuner_intcnd_f; /* INTCNDD_F register */
  78. unsigned char g_tuner_intcnd_s; /* INTCNDD_S register */
  79. unsigned char g_tuner_intst_f;
  80. unsigned char g_tuner_intst_s;
  81. /* kernel_thread */
  82. struct task_struct *g_tuner_kthread_id; /* identifier */
  83. u32 g_tuner_kthread_flag; /* flag */
  84. wait_queue_head_t g_tuner_kthread_wait_queue; /* wait queue */
  85. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  86. /* mutex */
  87. struct mutex g_tuner_mutex; /* exclusive control */
  88. #endif
  89. #if defined(CONFIG_TMM_ANT_DET)
  90. #define DPRINTK printk
  91. static struct wake_lock isdbtmm_ant_wlock;
  92. #endif
  93. struct isdbtmm_platform_data *isdbtmm_pdata;
  94. /******************************************************************************
  95. * function
  96. ******************************************************************************/
  97. static ssize_t tuner_module_entry_read( struct file* FIle,
  98. char* Buffer,
  99. size_t Count,
  100. loff_t* OffsetPosition );
  101. static ssize_t tuner_module_entry_write( struct file* FIle,
  102. const char* Buffer,
  103. size_t Count,
  104. loff_t* OffsetPosition );
  105. static unsigned int tuner_module_entry_poll( struct file *file,
  106. struct poll_table_struct *poll_tbl );
  107. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
  108. static int tuner_module_entry_ioctl( struct inode* Inode,
  109. struct file* FIle,
  110. unsigned int uCommand,
  111. unsigned long uArgument );
  112. #else /* LINUX_VERSION_CODE */
  113. static long tuner_module_entry_ioctl( struct file *file,
  114. unsigned int uCommand,
  115. unsigned long uArgument );
  116. #endif /* LINUX_VERSION_CODE */
  117. static int tuner_module_entry_open( struct inode* Inode,
  118. struct file* FIle );
  119. static int tuner_module_entry_close( struct inode* Inode,
  120. struct file* FIle );
  121. static int tuner_probe( struct platform_device *pdev );
  122. static int tuner_remove( struct platform_device *pdev );
  123. /* entry point */
  124. static struct file_operations TunerFileOperations = {
  125. .owner = THIS_MODULE,
  126. .read = tuner_module_entry_read,
  127. .write = tuner_module_entry_write,
  128. .poll = tuner_module_entry_poll,
  129. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
  130. .ioctl = tuner_module_entry_ioctl,
  131. #else /* LINUX_VERSION_CODE */
  132. .unlocked_ioctl = tuner_module_entry_ioctl,
  133. #endif /* LINUX_VERSION_CODE */
  134. .open = tuner_module_entry_open,
  135. .release = tuner_module_entry_close
  136. };
  137. static const struct of_device_id isdbtmm_match_table[] = {
  138. { .compatible = "isdbtmm_pdata",
  139. },
  140. {}
  141. };
  142. static struct platform_driver mmtuner_driver = {
  143. .probe = tuner_probe,
  144. .remove = tuner_remove,
  145. .driver = { .name = "tmmi2c",
  146. .owner = THIS_MODULE,
  147. .of_match_table = isdbtmm_match_table,
  148. }
  149. };
  150. static struct platform_device *mmtuner_device;
  151. static struct class *device_class;
  152. /* Add Start 20121218 No_1 */
  153. static unsigned long open_cnt = 0; /* OPEN counter */
  154. static long moni_cnt = 0; /* Monitor counter */
  155. /* Add End 20121218 No_1 */
  156. #ifndef TUNER_CONFIG_IRQ_PC_LINUX
  157. irqreturn_t tuner_interrupt( int irq, void *dev_id );
  158. #else /* TUNER_CONFIG_IRQ_PC_LINUX */
  159. int tuner_interrupt( void );
  160. #endif /* TUNER_CONFIG_IRQ_PC_LINUX */
  161. /******************************************************************************
  162. * code area
  163. ******************************************************************************/
  164. #if defined(CONFIG_TMM_ANT_DET)
  165. enum {
  166. ISDBTMM_ANT_OPEN = 0,
  167. ISDBTMM_ANT_CLOSE,
  168. ISDBTMM_ANT_UNKNOWN,
  169. };
  170. enum {
  171. ISDBTMM_ANT_DET_LOW = 0,
  172. ISDBTMM_ANT_DET_HIGH,
  173. };
  174. static struct input_dev *isdbtmm_ant_input;
  175. static int isdbtmm_check_ant;
  176. static int ant_prev_status;
  177. #define ISDBTMM_ANT_WAIT_INIT_TIME 500000 /* us */
  178. #define ISDBTMM_ANT_CHECK_DURATION 50000 /* us */
  179. #define ISDBTMM_ANT_CHECK_COUNT 10
  180. #define ISDBTMM_ANT_WLOCK_TIMEOUT \
  181. ((ISDBTMM_ANT_CHECK_DURATION * ISDBTMM_ANT_CHECK_COUNT * 2) / 500000)
  182. static int isdbtmm_ant_det_check_value(void)
  183. {
  184. int loop = 0, cur_val = 0;
  185. int ret = ISDBTMM_ANT_UNKNOWN;
  186. isdbtmm_check_ant = 1;
  187. DPRINTK("%s ant_prev_status(%d)\n",
  188. __func__, ant_prev_status);
  189. usleep_range(ISDBTMM_ANT_WAIT_INIT_TIME, ISDBTMM_ANT_WAIT_INIT_TIME); /* wait initial noise */
  190. for (loop = 0; loop < ISDBTMM_ANT_CHECK_COUNT; loop++) {
  191. usleep_range(ISDBTMM_ANT_CHECK_DURATION, ISDBTMM_ANT_CHECK_DURATION);
  192. cur_val = gpio_get_value_cansleep(isdbtmm_pdata->gpio_ant_det);
  193. if (ant_prev_status == cur_val)
  194. break;
  195. }
  196. if (loop == ISDBTMM_ANT_CHECK_COUNT) {
  197. if (ant_prev_status == ISDBTMM_ANT_DET_LOW
  198. && cur_val == ISDBTMM_ANT_DET_HIGH) {
  199. ret = ISDBTMM_ANT_OPEN;
  200. } else if (ant_prev_status == ISDBTMM_ANT_DET_HIGH
  201. && cur_val == ISDBTMM_ANT_DET_LOW) {
  202. ret = ISDBTMM_ANT_CLOSE;
  203. }
  204. ant_prev_status = cur_val;
  205. }
  206. isdbtmm_check_ant = 0;
  207. DPRINTK("%s cnt(%d) cur(%d) prev(%d)\n",
  208. __func__, loop, cur_val, ant_prev_status);
  209. return ret;
  210. }
  211. static int isdbtmm_ant_det_ignore_irq(void)
  212. {
  213. DPRINTK("chk_ant=%d\n", isdbtmm_check_ant);
  214. return isdbtmm_check_ant;
  215. }
  216. static void isdbtmm_ant_det_work_func(struct work_struct *work)
  217. {
  218. if (!isdbtmm_ant_input) {
  219. DPRINTK("%s: input device is not registered\n", __func__);
  220. return;
  221. }
  222. switch (isdbtmm_ant_det_check_value()) {
  223. case ISDBTMM_ANT_OPEN:
  224. input_report_key(isdbtmm_ant_input, KEY_DMB_ANT_DET_UP, 1);
  225. input_report_key(isdbtmm_ant_input, KEY_DMB_ANT_DET_UP, 0);
  226. input_sync(isdbtmm_ant_input);
  227. DPRINTK("%s : ISDBTMM_ANT_OPEN\n", __func__);
  228. break;
  229. case ISDBTMM_ANT_CLOSE:
  230. input_report_key(isdbtmm_ant_input, KEY_DMB_ANT_DET_DOWN, 1);
  231. input_report_key(isdbtmm_ant_input, KEY_DMB_ANT_DET_DOWN, 0);
  232. input_sync(isdbtmm_ant_input);
  233. DPRINTK("%s : ISDBTMM_ANT_CLOSE\n", __func__);
  234. break;
  235. case ISDBTMM_ANT_UNKNOWN:
  236. DPRINTK("%s : ISDBTMM_ANT_UNKNOWN\n", __func__);
  237. break;
  238. default:
  239. break;
  240. }
  241. }
  242. static struct workqueue_struct *isdbtmm_ant_det_wq;
  243. static DECLARE_WORK(isdbtmm_ant_det_work, isdbtmm_ant_det_work_func);
  244. static bool isdbtmm_ant_det_reg_input(struct platform_device *pdev)
  245. {
  246. struct input_dev *input;
  247. int err;
  248. DPRINTK("%s\n", __func__);
  249. input = input_allocate_device();
  250. if (!input) {
  251. DPRINTK("Can't allocate input device\n");
  252. err = -ENOMEM;
  253. }
  254. set_bit(EV_KEY, input->evbit);
  255. set_bit(KEY_DMB_ANT_DET_UP & KEY_MAX, input->keybit);
  256. set_bit(KEY_DMB_ANT_DET_DOWN & KEY_MAX, input->keybit);
  257. input->name = "sec_dmb_key";
  258. input->phys = "sec_dmb_key/input0";
  259. input->dev.parent = &pdev->dev;
  260. err = input_register_device(input);
  261. if (err) {
  262. DPRINTK("Can't register dmb_ant_det key: %d\n", err);
  263. goto free_input_dev;
  264. }
  265. isdbtmm_ant_input = input;
  266. ant_prev_status = gpio_get_value_cansleep(isdbtmm_pdata->gpio_ant_det);
  267. return true;
  268. free_input_dev:
  269. input_free_device(input);
  270. return false;
  271. }
  272. static void isdbtmm_ant_det_unreg_input(void)
  273. {
  274. DPRINTK("%s\n", __func__);
  275. if (isdbtmm_ant_input) {
  276. input_unregister_device(isdbtmm_ant_input);
  277. isdbtmm_ant_input = NULL;
  278. }
  279. }
  280. static bool isdbtmm_ant_det_create_wq(void)
  281. {
  282. DPRINTK("%s\n", __func__);
  283. isdbtmm_ant_det_wq = create_singlethread_workqueue("isdbtmm_ant_det_wq");
  284. if (isdbtmm_ant_det_wq)
  285. return true;
  286. else
  287. return false;
  288. }
  289. static bool isdbtmm_ant_det_destroy_wq(void)
  290. {
  291. DPRINTK("%s\n", __func__);
  292. if (isdbtmm_ant_det_wq) {
  293. flush_workqueue(isdbtmm_ant_det_wq);
  294. destroy_workqueue(isdbtmm_ant_det_wq);
  295. isdbtmm_ant_det_wq = NULL;
  296. }
  297. return true;
  298. }
  299. static irqreturn_t isdbtmm_ant_det_irq_handler(int irq, void *dev_id)
  300. {
  301. DPRINTK("%s queue_work called\n", __func__);
  302. if (isdbtmm_ant_det_ignore_irq())
  303. return IRQ_HANDLED;
  304. wake_lock_timeout(&isdbtmm_ant_wlock, ISDBTMM_ANT_WLOCK_TIMEOUT * HZ);
  305. if (isdbtmm_ant_det_wq) {
  306. int ret = queue_work(isdbtmm_ant_det_wq, &isdbtmm_ant_det_work);
  307. if (ret == 0)
  308. DPRINTK("%s queue_work fail\n", __func__);
  309. }
  310. return IRQ_HANDLED;
  311. }
  312. static bool isdbtmm_ant_det_irq_set(bool set)
  313. {
  314. bool ret = true;
  315. DPRINTK("%s set= %d\n", __func__,set);
  316. if (set) {
  317. int irq_ret;
  318. isdbtmm_pdata->irq_ant_det = gpio_to_irq(isdbtmm_pdata->gpio_ant_det);
  319. irq_set_irq_type(isdbtmm_pdata->irq_ant_det
  320. , IRQ_TYPE_EDGE_BOTH);
  321. irq_ret = request_irq(isdbtmm_pdata->irq_ant_det
  322. , isdbtmm_ant_det_irq_handler
  323. , IRQF_DISABLED
  324. , "isdbtmm_ant_det"
  325. , NULL);
  326. if (irq_ret < 0) {
  327. DPRINTK("Error:%s request_irq %d\r\n", __func__, irq_ret);
  328. ret = false;
  329. }
  330. enable_irq_wake(isdbtmm_pdata->irq_ant_det);
  331. DPRINTK("%s irq = %d \r\n", __func__, isdbtmm_pdata->irq_ant_det);
  332. } else {
  333. disable_irq_wake(isdbtmm_pdata->irq_ant_det);
  334. free_irq(isdbtmm_pdata->irq_ant_det, NULL);
  335. }
  336. return ret;
  337. }
  338. #endif
  339. static struct isdbtmm_platform_data *isdbtmm_populate_dt_pdata(struct device *dev)
  340. {
  341. struct isdbtmm_platform_data *pdata;
  342. printk("%s\n", __func__);
  343. pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
  344. if (!pdata) {
  345. pr_err("%s : could not allocate memory for platform data\n", __func__);
  346. goto err;
  347. }
  348. #ifdef CONFIG_TMM_ANT_DET
  349. pdata->gpio_ant_det = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-ant-det-gpio", 0);
  350. if (pdata->gpio_ant_det < 0) {
  351. pr_err("%s : can not find the isdbt-detect-gpio gpio_ant_det in the dt\n", __func__);
  352. goto alloc_err;
  353. } else
  354. pr_info("%s : isdbt-detect-gpio gpio_ant_det =%d\n", __func__, pdata->gpio_ant_det);
  355. #endif
  356. pdata->gpio_en = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-gpio-pwr-en", 0);
  357. if (pdata->gpio_en < 0) {
  358. pr_err("%s : can not find the isdbt-detect-gpio gpio_en in the dt\n", __func__);
  359. goto alloc_err;
  360. } else
  361. pr_info("%s : isdbt-detect-gpio gpio_en =%d\n", __func__, pdata->gpio_en);
  362. pdata->gpio_rst = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-gpio-rst", 0);
  363. if (pdata->gpio_rst < 0) {
  364. pr_err("%s : can not find the isdbt-detect-gpio gpio_rst in the dt\n", __func__);
  365. goto alloc_err;
  366. } else
  367. pr_info("%s : isdbt-detect-gpio gpio_rst =%d\n", __func__, pdata->gpio_rst);
  368. pdata->gpio_int = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-gpio-irq", 0);
  369. if (pdata->gpio_int < 0) {
  370. pr_err("%s : can not find the isdbt-detect-gpio in the gpio_int dt\n", __func__);
  371. goto alloc_err;
  372. } else
  373. pr_info("%s : isdbt-detect-gpio gpio_int =%d\n", __func__, pdata->gpio_int);
  374. pdata->gpio_spi_do = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-gpio-spi_do", 0);
  375. if (pdata->gpio_spi_do < 0) {
  376. pr_err("%s : can not find the isdbt-detect-gpio in the gpio_spi_do dt\n", __func__);
  377. goto alloc_err;
  378. } else
  379. pr_info("%s : isdbt-detect-gpio gpio_spi_do =%d\n", __func__, pdata->gpio_spi_do);
  380. pdata->gpio_spi_di = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-gpio-spi_di", 0);
  381. if (pdata->gpio_spi_di < 0) {
  382. pr_err("%s : can not find the isdbt-detect-gpio in the gpio_spi_di dt\n", __func__);
  383. goto alloc_err;
  384. } else
  385. pr_info("%s : isdbt-detect-gpio gpio_spi_di =%d\n", __func__, pdata->gpio_spi_di);
  386. pdata->gpio_spi_cs = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-gpio-spi_cs", 0);
  387. if (pdata->gpio_spi_cs < 0) {
  388. pr_err("%s : can not find the isdbt-detect-gpio gpio_spi_cs in the dt\n", __func__);
  389. goto alloc_err;
  390. } else
  391. pr_info("%s : isdbt-detect-gpio gpio_spi_cs=%d\n", __func__, pdata->gpio_spi_cs);
  392. pdata->gpio_spi_clk = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-gpio-spi_clk", 0);
  393. if (pdata->gpio_spi_clk < 0) {
  394. pr_err("%s : can not find the isdbt-detect-gpio gpio_spi_clk in the dt\n", __func__);
  395. goto alloc_err;
  396. } else
  397. pr_info("%s : isdbt-detect-gpio gpio_spi_clk=%d\n", __func__, pdata->gpio_spi_clk);
  398. pdata->gpio_i2c_sda = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-gpio-i2c_sda", 0);
  399. if (pdata->gpio_i2c_sda < 0) {
  400. pr_err("%s : can not find the isdbt-detect-gpio gpio_i2c_sda in the dt\n", __func__);
  401. goto alloc_err;
  402. } else
  403. pr_info("%s : isdbt-detect-gpio gpio_i2c_sda=%d\n", __func__, pdata->gpio_i2c_sda);
  404. pdata->gpio_i2c_scl = of_get_named_gpio(dev->of_node, "qcom,isdbtmm-gpio-i2c_scl", 0);
  405. if (pdata->gpio_i2c_scl < 0) {
  406. pr_err("%s : can not find the isdbt-detect-gpio gpio_i2c_scl in the dt\n", __func__);
  407. goto alloc_err;
  408. } else
  409. pr_info("%s : isdbt-detect-gpio gpio_i2c_scl=%d\n", __func__, pdata->gpio_i2c_scl);
  410. return pdata;
  411. alloc_err:
  412. devm_kfree(dev, pdata);
  413. err:
  414. return NULL;
  415. }
  416. /******************************************************************************
  417. * function: tuner_probe
  418. * brief : probe control of a driver
  419. * date : 2011.08.02
  420. * author : K.Kitamura(*)
  421. *
  422. * return : 0 normal exit
  423. * : -1 error exit
  424. * input : pdev
  425. * output : none
  426. ******************************************************************************/
  427. static int tuner_probe(struct platform_device *pdev)
  428. {
  429. int ret;
  430. printk("mmtuner_probe: Called.\n");
  431. /* tuner register */
  432. if (register_chrdev(TUNER_CONFIG_DRV_MAJOR, TUNER_CONFIG_DRIVER_NAME,
  433. &TunerFileOperations))
  434. {
  435. ERROR_PRINT("mmtuner_probe: register_chrdev()\
  436. Failed Major:%d.", TUNER_CONFIG_DRV_MAJOR);
  437. return -1;
  438. }
  439. isdbtmm_pdata = isdbtmm_populate_dt_pdata(&pdev->dev);
  440. if (!isdbtmm_pdata) {
  441. pr_err("%s : isdbt_pdata is NULL.\n", __func__);
  442. return -ENODEV;
  443. }
  444. /* initialization of external variable */
  445. init_waitqueue_head( &g_tuner_poll_wait_queue );
  446. spin_lock_init( &g_tuner_lock );
  447. g_tuner_wakeup_flag = TUNER_OFF;
  448. g_tuner_intcnd_f = 0x00;
  449. g_tuner_intcnd_s = 0x00;
  450. open_cnt = 0;
  451. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  452. mutex_init(&g_tuner_mutex);
  453. #endif
  454. printk("tuner_probe: END.\n");
  455. #if defined(CONFIG_TMM_ANT_DET)
  456. wake_lock_init(&isdbtmm_ant_wlock, WAKE_LOCK_SUSPEND, "isdbtmm_ant_wlock");
  457. if (!isdbtmm_ant_det_reg_input(pdev))
  458. goto err_reg_input;
  459. if (!isdbtmm_ant_det_create_wq())
  460. goto free_reg_input;
  461. if (!isdbtmm_ant_det_irq_set(true))
  462. goto free_ant_det_wq;
  463. #endif
  464. /* NORMAL END */
  465. return 0;
  466. #if defined(CONFIG_TMM_ANT_DET)
  467. free_ant_det_wq:
  468. isdbtmm_ant_det_destroy_wq();
  469. free_reg_input:
  470. isdbtmm_ant_det_unreg_input();
  471. err_reg_input:
  472. ret = -EFAULT;
  473. #endif
  474. /* ERROR END */
  475. return ret;
  476. }
  477. /******************************************************************************
  478. * function: tuner_remove
  479. * brief : remove control of a driver
  480. * date : 2011.08.02
  481. * author : K.Kitamura(*)
  482. *
  483. * return : 0 normal exit
  484. * : -1 error exit
  485. * input : pdev
  486. * output : none
  487. ******************************************************************************/
  488. static int tuner_remove(struct platform_device *pdev)
  489. {
  490. printk("tuner_remove: Called.\n");
  491. TRACE();
  492. /* release of the interrupt */
  493. tuner_drv_release_interrupt();
  494. /* tuner unregister */
  495. unregister_chrdev(TUNER_CONFIG_DRV_MAJOR, TUNER_CONFIG_DRIVER_NAME);
  496. printk("tuner_remove: END.\n");
  497. #if defined(CONFIG_TMM_ANT_DET)
  498. isdbtmm_ant_det_unreg_input();
  499. isdbtmm_ant_det_destroy_wq();
  500. isdbtmm_ant_det_irq_set(false);
  501. wake_lock_destroy(&isdbtmm_ant_wlock);
  502. #endif
  503. return 0;
  504. }
  505. /******************************************************************************
  506. * function: tuner_kernel_thread
  507. * brief : kernel_thread of mmtuner driver
  508. * date : 2011.09.16
  509. * author : K.Kitamura(*)
  510. *
  511. * return : 0 normal exit
  512. * : -1 error exit
  513. * input : none
  514. * output : none
  515. ******************************************************************************/
  516. int tuner_kernel_thread( void * arg )
  517. {
  518. int ret = 0;
  519. unsigned long flags;
  520. unsigned long ktread_flg;
  521. mm_segment_t oldfs;
  522. struct sched_param param;
  523. struct i2c_adapter *adap;
  524. struct i2c_msg msgs[4];
  525. unsigned char buff[3];
  526. unsigned char bufs[3];
  527. printk("tuner_kernel_thread: START.\n");
  528. /* initialization of internal variables */
  529. ret = 0;
  530. flags = 0;
  531. ktread_flg = 0;
  532. adap = NULL;
  533. param.sched_priority = TUNER_CONFIG_KTH_PRI;
  534. daemonize( "tuner_kthread" );
  535. oldfs = get_fs();
  536. set_fs( KERNEL_DS );
  537. ret = sched_setscheduler( g_tuner_kthread_id, SCHED_FIFO, &param );
  538. set_fs( oldfs );
  539. buff[0] = (unsigned char)TUNER_DRV_ADR_INTCND_F;
  540. bufs[0] = (unsigned char)TUNER_DRV_ADR_INTCND_S;
  541. while(1)
  542. {
  543. DEBUG_PRINT("tuner_kernel_thread waiting... ");
  544. wait_event_interruptible( g_tuner_kthread_wait_queue,
  545. g_tuner_kthread_flag );
  546. spin_lock_irqsave( &g_tuner_lock, flags );
  547. ktread_flg = g_tuner_kthread_flag;
  548. g_tuner_kthread_flag &= ~TUNER_KTH_IRQHANDLER;
  549. spin_unlock_irqrestore( &g_tuner_lock, flags);
  550. memset( msgs, 0x00, sizeof(struct i2c_msg) * 4 );
  551. adap = i2c_get_adapter(TUNER_CONFIG_I2C_BUSNUM);
  552. if (adap == NULL) {
  553. TRACE();
  554. break;
  555. }
  556. /* get interrupt factor */
  557. if ( ( ktread_flg & TUNER_KTH_IRQHANDLER ) == TUNER_KTH_IRQHANDLER )
  558. {
  559. DEBUG_PRINT("tuner_kernel_thread IRQHANDLER start ");
  560. buff[1] = buff[2] = 0;
  561. bufs[1] = bufs[2] = 0;
  562. /* read data */
  563. /* INTCND_F */
  564. msgs[0].addr = TUNER_SLAVE_ADR_M1;
  565. msgs[0].flags = 0; /* write */
  566. msgs[0].len = 1;
  567. msgs[0].buf = &buff[0];
  568. msgs[1].addr = TUNER_SLAVE_ADR_M1;
  569. msgs[1].flags = I2C_M_RD;
  570. msgs[1].len = 2;
  571. msgs[1].buf = buff+1;
  572. msgs[2].addr = TUNER_SLAVE_ADR_M2;
  573. msgs[2].flags = 0; /* write */
  574. msgs[2].len = 1;
  575. msgs[2].buf = &bufs[0];
  576. msgs[3].addr = TUNER_SLAVE_ADR_M2;
  577. msgs[3].flags = I2C_M_RD;
  578. msgs[3].len = 2;
  579. msgs[3].buf = bufs+1;
  580. ret = i2c_transfer(adap, msgs, 4);
  581. if (ret < 0) {
  582. TRACE();
  583. break;
  584. }
  585. DEBUG_PRINT(
  586. "read slv:0x%02x adr:0x%02x len:%-4d 0x%02x ... 0x%02x ",
  587. msgs[0].addr, *(msgs[0].buf), msgs[1].len,
  588. msgs[1].buf[0], msgs[1].buf[1]);
  589. DEBUG_PRINT(
  590. "read slv:0x%02x adr:0x%02x len:%-4d 0x%02x ... 0x%02x ",
  591. msgs[2].addr, *(msgs[2].buf), msgs[3].len,
  592. msgs[3].buf[0], msgs[3].buf[1]);
  593. g_tuner_intcnd_f |= buff[1];
  594. g_tuner_intst_f |= buff[2];
  595. g_tuner_intcnd_s |= bufs[1];
  596. g_tuner_intst_s |= bufs[2];
  597. DEBUG_PRINT( "// IRQ factor update: INTCND_F:0x%02x INTST_F:0x%02x"
  598. ,g_tuner_intcnd_f, g_tuner_intst_f );
  599. DEBUG_PRINT( "// IRQ factor update: INTCND_S:0x%02x INTST_S:0x%02x"
  600. ,g_tuner_intcnd_s, g_tuner_intst_s );
  601. memset( msgs, 0x00, sizeof(struct i2c_msg) * 4 );
  602. msgs[0].addr = TUNER_SLAVE_ADR_M1;
  603. msgs[0].flags = 0; /* write */
  604. msgs[0].len = 2;
  605. msgs[0].buf = buff;
  606. msgs[1].addr = TUNER_SLAVE_ADR_M2;
  607. msgs[1].flags = 0; /* write */
  608. msgs[1].len = 2;
  609. msgs[1].buf = bufs;
  610. ret = i2c_transfer(adap, msgs, 2);
  611. if (ret < 0) {
  612. TRACE();
  613. i2c_put_adapter(adap);
  614. break;
  615. }
  616. i2c_put_adapter(adap);
  617. /* poll wait release */
  618. g_tuner_wakeup_flag = TUNER_ON;
  619. wake_up( &g_tuner_poll_wait_queue );
  620. DEBUG_PRINT("tuner_interrupt end ");
  621. #ifdef TUNER_CONFIG_IRQ_LEVELTRIGGER
  622. tuner_drv_enable_interrupt();
  623. #endif /* TUNER_CONFIG_IRQ_LEVELTRIGGER */
  624. }
  625. /* thread stop set */
  626. if ( ( ktread_flg & TUNER_KTH_END ) == TUNER_KTH_END )
  627. {
  628. DEBUG_PRINT("tuner_kernel_thread KTH_END start ");
  629. spin_lock_irqsave( &g_tuner_lock, flags );
  630. g_tuner_kthread_flag &= ~TUNER_KTH_END;
  631. spin_unlock_irqrestore( &g_tuner_lock, flags );
  632. break;
  633. }
  634. }
  635. INFO_PRINT("tuner_kernel_thread: END. ");
  636. return 0;
  637. }
  638. /******************************************************************************
  639. * function: tuner_drv_start
  640. * brief : initialization control of a driver
  641. * date : 2011.08.02
  642. * author : K.Kitamura(*)
  643. *
  644. * return : 0 normal exit
  645. * : -1 error exit
  646. * input : none
  647. * output : none
  648. ******************************************************************************/
  649. /* Modify Start 20121218 No_3 */
  650. #if 1
  651. int tuner_drv_start(void)
  652. #else
  653. static int __init tuner_drv_start(void)
  654. #endif
  655. /* Modify End 20121218 No_3 */
  656. {
  657. int ret =0;
  658. struct device *dev = NULL;
  659. printk("mmtuner_tuner_drv_start: Called\n");
  660. /* driver register */
  661. ret = platform_driver_register(&mmtuner_driver);
  662. if( ret != 0 )
  663. {
  664. ERROR_PRINT("init_module: Error:\
  665. failed in platform_driver_register.");
  666. return ret;
  667. }
  668. /* device alloc */
  669. mmtuner_device = platform_device_alloc(TUNER_CONFIG_DRIVER_NAME, -1);
  670. if (!mmtuner_device)
  671. {
  672. ERROR_PRINT("init_module: Error: failed in platform_device_alloc.");
  673. platform_driver_unregister(&mmtuner_driver);
  674. return -ENOMEM;
  675. }
  676. /* device add */
  677. ret = platform_device_add(mmtuner_device);
  678. if ( ret )
  679. {
  680. ERROR_PRINT("init_module: Error: failed in platform_device_add.");
  681. platform_device_put(mmtuner_device);
  682. platform_driver_unregister(&mmtuner_driver);
  683. return ret;
  684. }
  685. device_class = class_create(THIS_MODULE, TUNER_CONFIG_DRIVER_NAME);
  686. if (IS_ERR(device_class))
  687. {
  688. ERROR_PRINT("init_module: Error: failed in class_create.");
  689. platform_device_put(mmtuner_device);
  690. platform_driver_unregister(&mmtuner_driver);
  691. return PTR_ERR(device_class);
  692. }
  693. dev = device_create ( device_class,
  694. NULL,
  695. MKDEV(TUNER_CONFIG_DRV_MAJOR,
  696. TUNER_CONFIG_DRV_MINOR),
  697. NULL,
  698. TUNER_CONFIG_DRIVER_NAME);
  699. if(IS_ERR(dev))
  700. {
  701. ERROR_PRINT("init_module: Error: failed in device_create.");
  702. platform_device_put(mmtuner_device);
  703. platform_driver_unregister(&mmtuner_driver);
  704. return PTR_ERR(dev);
  705. }
  706. /* thread creat */
  707. g_tuner_kthread_flag = TUNER_KTH_NONE;
  708. init_waitqueue_head( &g_tuner_kthread_wait_queue );
  709. g_tuner_kthread_id = kthread_create( tuner_kernel_thread,
  710. NULL,
  711. "tuner_kthread" );
  712. if( IS_ERR( g_tuner_kthread_id ) )
  713. {
  714. g_tuner_kthread_id = NULL;
  715. platform_device_put(mmtuner_device);
  716. platform_driver_unregister(&mmtuner_driver);
  717. return -EIO;
  718. }
  719. wake_up_process( g_tuner_kthread_id );
  720. printk("mmtuner_tuner_drv_start: END\n");
  721. return 0;
  722. }
  723. /******************************************************************************
  724. * function: tuner_drv_end
  725. * brief : exit control of a driver
  726. * date : 2011.08.02
  727. * author : K.Kitamura(*)
  728. *
  729. * return : none
  730. * input : none
  731. * output : none
  732. ******************************************************************************/
  733. /* Modify Start 20121218 No_3 */
  734. #if 1
  735. void tuner_drv_end(void)
  736. #else
  737. static void __exit tuner_drv_end(void)
  738. #endif
  739. /* Modify End 20121218 No_3 */
  740. {
  741. printk("mmtuner_tuner_drv_end: Called\n");
  742. /* thread stop flag */
  743. g_tuner_kthread_flag |= TUNER_KTH_END;
  744. if( waitqueue_active( &g_tuner_kthread_wait_queue ))
  745. {
  746. wake_up( &g_tuner_kthread_wait_queue );
  747. }
  748. /* thread stop */
  749. if( g_tuner_kthread_id )
  750. {
  751. kthread_stop( g_tuner_kthread_id );
  752. }
  753. /* device destroy */
  754. device_destroy(device_class, MKDEV(TUNER_CONFIG_DRV_MAJOR,
  755. TUNER_CONFIG_DRV_MINOR));
  756. /* class destroy */
  757. class_destroy(device_class);
  758. /* device unregister */
  759. platform_device_unregister(mmtuner_device);
  760. /* driver unregister */
  761. platform_driver_unregister(&mmtuner_driver);
  762. printk("mmtuner_tuner_drv_end: END\n");
  763. }
  764. /******************************************************************************
  765. * function: tuner_module_entry_open
  766. * brief : open control of a driver
  767. * date : 2011.08.02
  768. * author : K.Kitamura(*)
  769. *
  770. * return : 0 normal exit
  771. * : -1 error exit
  772. * input : Inode
  773. * : FIle
  774. * output : none
  775. ******************************************************************************/
  776. static int tuner_module_entry_open(struct inode* Inode, struct file* FIle)
  777. {
  778. printk("tuner_module_entry_open: Called\n");
  779. #ifdef TUNER_CONFIG_DRV_MULTI /* allow multiple open */
  780. open_cnt++;
  781. #else /* TUNER_CONFIG_DRV_MULTI */ /* not allow multiple open */
  782. /* already open */
  783. if( open_cnt > 0 )
  784. {
  785. printk("tuner_module_entry_open: open error\n");
  786. return -1;
  787. }
  788. /* first open */
  789. else
  790. {
  791. printk("tuner_module_entry_open: open_cnt = 1\n");
  792. open_cnt++;
  793. }
  794. #endif /* TUNER_CONFIG_DRV_MULTI */
  795. INFO_PRINT("tuner_module_entry_open: end << open cnt = %ld >>",
  796. open_cnt );
  797. return 0;
  798. }
  799. /******************************************************************************
  800. * function: tuner_module_entry_close
  801. * brief : close control of a driver
  802. * date : 2011.08.02
  803. * author : K.Kitamura(*)
  804. *
  805. * return : 0 normal exit
  806. * : -1 error exit
  807. * input : Inode
  808. * : FIle
  809. * output : none
  810. ******************************************************************************/
  811. static int tuner_module_entry_close(struct inode* Inode, struct file* FIle)
  812. {
  813. struct devone_data *dev;
  814. printk("tuner_module_entry_close: Called\n");
  815. if( open_cnt <= 0 )
  816. {
  817. printk("tuner_module_entry_close: close error\n");
  818. open_cnt = 0;
  819. return -1;
  820. }
  821. else
  822. {
  823. open_cnt--;
  824. }
  825. /* close all open */
  826. if( open_cnt == 0 )
  827. {
  828. /* interrupt release */
  829. tuner_drv_release_interrupt();
  830. if( FIle == NULL )
  831. {
  832. return -1;
  833. }
  834. dev = FIle->private_data;
  835. if( dev )
  836. {
  837. kfree( dev );
  838. }
  839. }
  840. return 0;
  841. }
  842. /******************************************************************************
  843. * function: tuner_module_entry_read
  844. * brief : read control of a driver
  845. * date : 2011.08.02
  846. * author : K.Kitamura(*)
  847. *
  848. * return : 0 normal exit
  849. * : -1 error exit
  850. * input : FIle
  851. * : Buffer
  852. * : Count
  853. * : OffsetPosition
  854. * output : none
  855. ******************************************************************************/
  856. static ssize_t tuner_module_entry_read(struct file * FIle, char * Buffer,
  857. size_t Count, loff_t * OffsetPosition)
  858. {
  859. return 0;
  860. }
  861. /******************************************************************************
  862. * function: tuner_module_entry_write
  863. * brief : write control of a driver
  864. * date : 2011.10.31
  865. * author : K.Okawa(KXD14)
  866. *
  867. * return : 0 normal exit
  868. * : -1 error exit
  869. * input : FIle
  870. * : Buffer [slave][reg.addr][data-0][data-1]...[data-(n-1)]
  871. * : Count (>=3) n+2
  872. * : OffsetPosition
  873. * output : none
  874. ******************************************************************************/
  875. static ssize_t tuner_module_entry_write(struct file* FIle,
  876. const char* Buffer, size_t Count, loff_t* OffsetPosition)
  877. {
  878. int ret;
  879. unsigned long copy_ret;
  880. unsigned char *buf; /* pointer to data area */
  881. struct i2c_adapter *adap;
  882. struct i2c_msg msgs[1];
  883. /* argument check */
  884. if (Count < 3) {
  885. TRACE();
  886. return -EINVAL;
  887. }
  888. /* memory allocation for data area */
  889. buf = (unsigned char *)vmalloc(Count);
  890. if (buf == NULL) {
  891. return -EINVAL;
  892. }
  893. copy_ret = copy_from_user(buf, Buffer, Count);
  894. if (copy_ret != 0) {
  895. vfree(buf);
  896. return -EINVAL;
  897. }
  898. /* get i2c adapter */
  899. adap = i2c_get_adapter(TUNER_CONFIG_I2C_BUSNUM);
  900. if (adap == NULL) {
  901. TRACE();
  902. vfree(buf);
  903. return -EINVAL;
  904. }
  905. /* construct i2c message */
  906. memset(msgs, 0x00, sizeof(struct i2c_msg) * 1);
  907. msgs[0].addr = buf[0];
  908. msgs[0].flags = 0; /* write */
  909. msgs[0].len = Count - 1;
  910. msgs[0].buf = buf + 1;
  911. ret = i2c_transfer(adap, msgs, 1);
  912. if (ret < 0) {
  913. TRACE();
  914. i2c_put_adapter(adap);
  915. vfree(buf);
  916. return -EINVAL;
  917. }
  918. DEBUG_PRINT(
  919. "write slv:0x%02x adr:0x%02x len:%-4d 0x%02x ... 0x%02x ",
  920. buf[0], buf[1], Count-2, buf[2], buf[Count-1]);
  921. vfree(buf);
  922. return ret;
  923. }
  924. /* Add Start 20121218 No_1 */
  925. /******************************************************************************
  926. * function: SMT113J_IOCTL_GET_OPEN_COUNT
  927. * brief : ioctl control of a driver
  928. * date : 2011.08.02
  929. * author : K.Kitamura(*)
  930. *
  931. * return : 0 normal exit
  932. * : -1 error exit
  933. * input : Inode
  934. * : FIle
  935. * : uCommand
  936. * : uArgument
  937. * output : none
  938. ******************************************************************************/
  939. static int SMT113J_IOCTL_GET_OPEN_COUNT ( struct file* FIle,
  940. unsigned int cmd,
  941. unsigned long arg )
  942. {
  943. TUNER_STS_DATA *arg_data;
  944. int ret = 0;
  945. unsigned long temp_open = 0,
  946. temp_moni = 0;
  947. DEBUG_PRINT ("SMT113J_IOCTL_GET_OPEN_COUNT << Start >> : open = %ld",
  948. ( open_cnt - moni_cnt ));
  949. /* Parameter check */
  950. arg_data = (TUNER_STS_DATA*)arg;
  951. if ( NULL == arg_data )
  952. {
  953. ERROR_PRINT ("Parameter Error : arg = NULL");
  954. return ( -1 );
  955. }
  956. /* state check */
  957. if ( open_cnt < moni_cnt )
  958. {
  959. ERROR_PRINT ("-> Status Error : open = %ld, moni = %ld",
  960. open_cnt, moni_cnt );
  961. return ( -1 );
  962. }
  963. temp_open = (open_cnt - moni_cnt);
  964. temp_moni = moni_cnt;
  965. /* Copy to User Area */
  966. ret = put_user ( temp_open, (unsigned long __user *)&(arg_data->open_cnt) );
  967. if ( 0 != ret )
  968. {
  969. ERROR_PRINT ("-> put_user(arg_data->open_cnt) Error : ret = %d", ret );
  970. return ( -1 );
  971. }
  972. /* Copy to User Area */
  973. ret = put_user ( moni_cnt, (unsigned long __user *)&(arg_data->moni_cnt) );
  974. if ( 0 != ret )
  975. {
  976. ERROR_PRINT ("-> put_user(arg_data->moni_cnt) Error : ret = %d", ret );
  977. return ( -1 );
  978. }
  979. DEBUG_PRINT ("SMT113J_IOCTL_GET_OPEN_COUNT << End >>");
  980. DEBUG_PRINT ("-> Open Count Result : %ld", open_cnt );
  981. DEBUG_PRINT ("-> Monitor Count Result : %ld", moni_cnt );
  982. return ( 0 );
  983. }
  984. /******************************************************************************
  985. * function: SMT113J_IOCTL_SET_MONITOR_MODE
  986. * brief : ioctl control of a driver
  987. * date : 2011.08.02
  988. * author : K.Kitamura(*)
  989. *
  990. * return : 0 normal exit
  991. * : -1 error exit
  992. * input : Inode
  993. * : FIle
  994. * : uCommand
  995. * : uArgument
  996. * output : none
  997. ******************************************************************************/
  998. static int SMT113J_IOCTL_SET_MONITOR_MODE ( struct file* FIle,
  999. unsigned int cmd,
  1000. unsigned long arg )
  1001. {
  1002. int ret = 0;
  1003. DEBUG_PRINT ("SMT113J_IOCTL_SET_MONITOR_MODE << Start >> ");
  1004. if ( 1 == arg )
  1005. {
  1006. /* Monitor Mode Start */
  1007. moni_cnt++;
  1008. }
  1009. else
  1010. {
  1011. /* Monitor Mode Stop */
  1012. moni_cnt--;
  1013. if ( 0 > moni_cnt )
  1014. {
  1015. DEBUG_PRINT (" -> under counter = %ld => 0", moni_cnt );
  1016. moni_cnt = 0;
  1017. }
  1018. }
  1019. DEBUG_PRINT ("SMT113J_IOCTL_SET_MONITOR_MODE << End >> : moni_cnt = %ld",
  1020. moni_cnt );
  1021. return ( ret );
  1022. }
  1023. /* Add End 20121218 No_1 */
  1024. /******************************************************************************
  1025. * function: tuner_module_entry_ioctl
  1026. * brief : ioctl control of a driver
  1027. * date : 2011.08.02
  1028. * author : K.Kitamura(*)
  1029. *
  1030. * return : 0 normal exit
  1031. * : -1 error exit
  1032. * input : Inode
  1033. * : FIle
  1034. * : uCommand
  1035. * : uArgument
  1036. * output : none
  1037. ******************************************************************************/
  1038. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
  1039. static int tuner_module_entry_ioctl(struct inode* Inode, struct file* FIle,
  1040. unsigned int uCommand, unsigned long uArgument)
  1041. #else /* LINUX_VERSION_CODE */
  1042. static long tuner_module_entry_ioctl(struct file *file,
  1043. unsigned int uCommand, unsigned long uArgument)
  1044. #endif /* LINUX_VERSION_CODE */
  1045. {
  1046. int ret;
  1047. TUNER_DATA_RW data;
  1048. unsigned long copy_ret;
  1049. int param;
  1050. TUNER_DATA_RW event_status[ TUNER_EVENT_REGNUM ];
  1051. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1052. /* get lock */
  1053. mutex_lock(&g_tuner_mutex);
  1054. #endif
  1055. /* argument check */
  1056. if( uArgument == 0 )
  1057. {
  1058. TRACE();
  1059. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1060. /* lock release */
  1061. mutex_unlock(&g_tuner_mutex);
  1062. #endif
  1063. return -EINVAL;
  1064. }
  1065. switch( uCommand )
  1066. {
  1067. /* read data */
  1068. case TUNER_IOCTL_VALGET:
  1069. copy_ret = copy_from_user( &data,
  1070. &( *(TUNER_DATA_RW *)uArgument ),
  1071. sizeof( TUNER_DATA_RW ));
  1072. if( copy_ret != 0 )
  1073. {
  1074. TRACE();
  1075. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1076. /* lock release */
  1077. mutex_unlock(&g_tuner_mutex);
  1078. #endif
  1079. return -EINVAL;
  1080. }
  1081. ret = tuner_drv_hw_access( uCommand, &data, 1 );
  1082. if( ret == 0 )
  1083. {
  1084. copy_ret = copy_to_user( &( *(TUNER_DATA_RW *)uArgument ),
  1085. &data,
  1086. sizeof( TUNER_DATA_RW ));
  1087. if( copy_ret != 0 )
  1088. {
  1089. TRACE();
  1090. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1091. /* lock release */
  1092. mutex_unlock(&g_tuner_mutex);
  1093. #endif
  1094. return -EINVAL;
  1095. }
  1096. }
  1097. break;
  1098. /* write data */
  1099. case TUNER_IOCTL_VALSET:
  1100. copy_ret = copy_from_user( &data,
  1101. &( *(TUNER_DATA_RW *)uArgument ),
  1102. sizeof( TUNER_DATA_RW ));
  1103. if( copy_ret != 0 )
  1104. {
  1105. TRACE();
  1106. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1107. /* lock release */
  1108. mutex_unlock(&g_tuner_mutex);
  1109. #endif
  1110. return -EINVAL;
  1111. }
  1112. ret = tuner_drv_hw_access( uCommand, &data, 1 );
  1113. break;
  1114. case TUNER_IOCTL_VALGET_EVENT:
  1115. /* INTCND_F */
  1116. copy_ret = copy_to_user( &( *( unsigned char *)uArgument ),
  1117. &g_tuner_intcnd_f,
  1118. sizeof( unsigned char ));
  1119. if (copy_ret != 0) {
  1120. TRACE();
  1121. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1122. /* lock release */
  1123. mutex_unlock(&g_tuner_mutex);
  1124. #endif
  1125. return -EINVAL;
  1126. }
  1127. /* INTCND_S */
  1128. copy_ret = copy_to_user( &( *( unsigned char *)( uArgument + 1 )),
  1129. &g_tuner_intcnd_s,
  1130. sizeof( unsigned char ));
  1131. if (copy_ret != 0) {
  1132. TRACE();
  1133. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1134. /* lock release */
  1135. mutex_unlock(&g_tuner_mutex);
  1136. #endif
  1137. return -EINVAL;
  1138. }
  1139. /* INTST_F */
  1140. copy_ret = copy_to_user( &( *( unsigned char *)(uArgument + 2)),
  1141. &g_tuner_intst_f,
  1142. sizeof( unsigned char ));
  1143. if (copy_ret != 0) {
  1144. TRACE();
  1145. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1146. /* lock release */
  1147. mutex_unlock(&g_tuner_mutex);
  1148. #endif
  1149. return -EINVAL;
  1150. }
  1151. /* INTCND_F */
  1152. copy_ret = copy_to_user( &( *( unsigned char *)(uArgument + 3)),
  1153. &g_tuner_intst_s,
  1154. sizeof( unsigned char ));
  1155. if (copy_ret != 0) {
  1156. TRACE();
  1157. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1158. /* lock release */
  1159. mutex_unlock(&g_tuner_mutex);
  1160. #endif
  1161. return -EINVAL;
  1162. }
  1163. DEBUG_PRINT( "// IRQ factor send: INTCND_F:0x%02x INTST_F:0x%02x"
  1164. ,g_tuner_intcnd_f, g_tuner_intst_f );
  1165. DEBUG_PRINT( "// IRQ factor send: INTCND_S:0x%02x INTST_S:0x%02x"
  1166. ,g_tuner_intcnd_s, g_tuner_intst_s );
  1167. /* initialization */
  1168. g_tuner_intcnd_f = 0x00;
  1169. g_tuner_intcnd_s = 0x00;
  1170. g_tuner_intst_f = 0x00;
  1171. g_tuner_intst_s = 0x00;
  1172. ret = copy_ret;
  1173. break;
  1174. /* event set */
  1175. case TUNER_IOCTL_VALSET_EVENT:
  1176. DEBUG_PRINT("*** VALSET_EVENT ***");
  1177. copy_ret = copy_from_user( &data,
  1178. &( *(TUNER_DATA_RW *)uArgument ),
  1179. sizeof( TUNER_DATA_RW ));
  1180. if( copy_ret != 0 )
  1181. {
  1182. TRACE();
  1183. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1184. /* lock release */
  1185. mutex_unlock(&g_tuner_mutex);
  1186. #endif
  1187. return -EINVAL;
  1188. }
  1189. /* when 1st time of event setting, be enable interrupt */
  1190. /* slave address */
  1191. event_status[0].slave_adr = TUNER_SLAVE_ADR_M1;
  1192. /* reg. address */
  1193. event_status[0].adr = REG_INTDEF1_F;
  1194. /* start bit position */
  1195. event_status[0].sbit = SIG_ENS_INTDEF1_F;
  1196. /* end bit position */
  1197. event_status[0].ebit = SIG_ENE_INTDEF1_F;
  1198. /* clear for read */
  1199. event_status[0].param = 0x00;
  1200. /* enable bit mask */
  1201. event_status[0].enabit = SIG_ENA_INTDEF1_F;
  1202. event_status[1].slave_adr = TUNER_SLAVE_ADR_M1;
  1203. event_status[1].adr = REG_INTDEF2_F;
  1204. event_status[1].sbit = SIG_ENS_INTDEF2_F;
  1205. event_status[1].ebit = SIG_ENE_INTDEF2_F;
  1206. event_status[1].param = 0x00;
  1207. event_status[1].enabit = SIG_ENA_INTDEF2_F;
  1208. event_status[2].slave_adr = TUNER_SLAVE_ADR_M2;
  1209. event_status[2].adr = REG_INTDEF1_S;
  1210. event_status[2].sbit = SIG_ENS_INTDEF1_S;
  1211. event_status[2].ebit = SIG_ENE_INTDEF1_S;
  1212. event_status[2].param = 0x00;
  1213. event_status[2].enabit = SIG_ENA_INTDEF1_S;
  1214. event_status[3].slave_adr = TUNER_SLAVE_ADR_M2;
  1215. event_status[3].adr = REG_INTDEF2_S;
  1216. event_status[3].sbit = SIG_ENS_INTDEF2_S;
  1217. event_status[3].ebit = SIG_ENE_INTDEF2_S;
  1218. event_status[3].param = 0x00;
  1219. event_status[3].enabit = SIG_ENA_INTDEF2_S;
  1220. ret = tuner_drv_hw_access( TUNER_IOCTL_VALGET,
  1221. event_status,
  1222. TUNER_EVENT_REGNUM );
  1223. if( ret != 0 )
  1224. {
  1225. TRACE();
  1226. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1227. /* lock release */
  1228. mutex_unlock(&g_tuner_mutex);
  1229. #endif
  1230. return -EINVAL;
  1231. }
  1232. if (((event_status[0].param & event_status[0].enabit) == 0x00) &&
  1233. ((event_status[1].param & event_status[1].enabit) == 0x00) &&
  1234. ((event_status[2].param & event_status[2].enabit) == 0x00) &&
  1235. ((event_status[3].param & event_status[3].enabit) == 0x00))
  1236. {
  1237. DEBUG_PRINT("*** REQUEST IRQ ***");
  1238. ret = tuner_drv_set_interrupt();
  1239. if( ret != 0 )
  1240. {
  1241. TRACE();
  1242. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1243. /* lock release */
  1244. mutex_unlock(&g_tuner_mutex);
  1245. #endif
  1246. return -EINVAL;
  1247. }
  1248. }
  1249. ret = tuner_drv_hw_access( TUNER_IOCTL_VALSET, &data, 1 );
  1250. break;
  1251. /* event release */
  1252. case TUNER_IOCTL_VALREL_EVENT:
  1253. copy_ret = copy_from_user( &data,
  1254. &( *(TUNER_DATA_RW *)uArgument ),
  1255. sizeof( TUNER_DATA_RW ));
  1256. if( copy_ret != 0 )
  1257. {
  1258. TRACE();
  1259. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1260. /* lock release */
  1261. mutex_unlock(&g_tuner_mutex);
  1262. #endif
  1263. return -EINVAL;
  1264. }
  1265. ret = tuner_drv_hw_access( TUNER_IOCTL_VALSET, &data, 1 );
  1266. if( ret != 0 )
  1267. {
  1268. TRACE();
  1269. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1270. /* lock release */
  1271. mutex_unlock(&g_tuner_mutex);
  1272. #endif
  1273. return -EINVAL;
  1274. }
  1275. /* slave address */
  1276. event_status[0].slave_adr = TUNER_SLAVE_ADR_M1;
  1277. /* reg. address */
  1278. event_status[0].adr = REG_INTDEF1_F;
  1279. /* start bit position */
  1280. event_status[0].sbit = SIG_ENS_INTDEF1_F;
  1281. /* end bit position */
  1282. event_status[0].ebit = SIG_ENE_INTDEF1_F;
  1283. /* clear for read */
  1284. event_status[0].param = 0x00;
  1285. /* enable bit mask */
  1286. event_status[0].enabit = SIG_ENA_INTDEF1_F;
  1287. event_status[1].slave_adr = TUNER_SLAVE_ADR_M1;
  1288. event_status[1].adr = REG_INTDEF2_F;
  1289. event_status[1].sbit = SIG_ENS_INTDEF2_F;
  1290. event_status[1].ebit = SIG_ENE_INTDEF2_F;
  1291. event_status[1].param = 0x00;
  1292. event_status[1].enabit = SIG_ENA_INTDEF2_F;
  1293. event_status[2].slave_adr = TUNER_SLAVE_ADR_M2;
  1294. event_status[2].adr = REG_INTDEF1_S;
  1295. event_status[2].sbit = SIG_ENS_INTDEF1_S;
  1296. event_status[2].ebit = SIG_ENE_INTDEF1_S;
  1297. event_status[2].param = 0x00;
  1298. event_status[2].enabit = SIG_ENA_INTDEF1_S;
  1299. event_status[3].slave_adr = TUNER_SLAVE_ADR_M2;
  1300. event_status[3].adr = REG_INTDEF2_S;
  1301. event_status[3].sbit = SIG_ENS_INTDEF2_S;
  1302. event_status[3].ebit = SIG_ENE_INTDEF2_S;
  1303. event_status[3].param = 0x00;
  1304. event_status[3].enabit = SIG_ENA_INTDEF2_S;
  1305. ret = tuner_drv_hw_access( TUNER_IOCTL_VALGET,
  1306. event_status,
  1307. TUNER_EVENT_REGNUM );
  1308. if (((event_status[0].param & event_status[0].enabit) == 0x00) &&
  1309. ((event_status[1].param & event_status[1].enabit) == 0x00) &&
  1310. ((event_status[2].param & event_status[2].enabit) == 0x00) &&
  1311. ((event_status[3].param & event_status[3].enabit) == 0x00))
  1312. {
  1313. DEBUG_PRINT("*** release IRQ REQUEST ***");
  1314. tuner_drv_release_interrupt();
  1315. }
  1316. break;
  1317. case TUNER_IOCTL_VALSET_POWER:
  1318. copy_ret = copy_from_user( &param,
  1319. &( *( int * )uArgument ),
  1320. sizeof( int ));
  1321. if( copy_ret != 0 )
  1322. {
  1323. TRACE();
  1324. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1325. /* lock release */
  1326. mutex_unlock(&g_tuner_mutex);
  1327. #endif
  1328. return -EINVAL;
  1329. }
  1330. ret = tuner_drv_ctl_power( param );
  1331. break;
  1332. /* Add Start 20121218 No_1 */
  1333. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
  1334. case TUNER_IOCTL_VALGET_OPENCNT:
  1335. ret = SMT113J_IOCTL_GET_OPEN_COUNT ( FIle->private_data,
  1336. uCommand,
  1337. uArgument );
  1338. break;
  1339. case TUNER_IOCTL_VALSET_MONICNT:
  1340. ret = SMT113J_IOCTL_SET_MONITOR_MODE ( FIle->private_data,
  1341. uCommand,
  1342. uArgument );
  1343. break;
  1344. #else /* LINUX_VERSION_CODE */
  1345. case TUNER_IOCTL_VALGET_OPENCNT:
  1346. ret = SMT113J_IOCTL_GET_OPEN_COUNT ( file->private_data,
  1347. uCommand,
  1348. uArgument );
  1349. break;
  1350. case TUNER_IOCTL_VALSET_MONICNT:
  1351. ret = SMT113J_IOCTL_SET_MONITOR_MODE ( file->private_data,
  1352. uCommand,
  1353. uArgument );
  1354. break;
  1355. #endif /* LINUX_VERSION_CODE */
  1356. /* Add End 20121218 No_1 */
  1357. default:
  1358. TRACE();
  1359. ret = -EINVAL;
  1360. break;
  1361. }
  1362. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
  1363. /* lock release */
  1364. mutex_unlock(&g_tuner_mutex);
  1365. #endif
  1366. return ret;
  1367. }
  1368. /******************************************************************************
  1369. * function: tuner_module_entry_poll
  1370. * brief : poll control of a driver
  1371. * date : 2011.08.23
  1372. * author : M.Takahashi(*)
  1373. *
  1374. * return : 0 normal exit
  1375. * : -1 error exit
  1376. * input : file
  1377. * : poll_tbl
  1378. * output : none
  1379. ******************************************************************************/
  1380. static unsigned int tuner_module_entry_poll(
  1381. struct file *file,
  1382. struct poll_table_struct *poll_tbl )
  1383. {
  1384. unsigned long tuner_flags;
  1385. unsigned int tuner_mask;
  1386. /* Initialization */
  1387. tuner_mask = 0;
  1388. /* poll wait */
  1389. poll_wait( file, &g_tuner_poll_wait_queue, poll_tbl );
  1390. /* interrupt disable */
  1391. spin_lock_irqsave( &g_tuner_lock, tuner_flags );
  1392. if( g_tuner_wakeup_flag == TUNER_ON )
  1393. {
  1394. tuner_mask = ( POLLIN | POLLRDNORM );
  1395. }
  1396. g_tuner_wakeup_flag = TUNER_OFF;
  1397. /* interrupt enable */
  1398. spin_unlock_irqrestore( &g_tuner_lock, tuner_flags );
  1399. return tuner_mask;
  1400. }
  1401. /******************************************************************************
  1402. * function: tuner_interrupt
  1403. * brief : interrpu control of a driver
  1404. * date : 2011.08.23
  1405. * author : M.Takahashi(*)
  1406. *
  1407. * return : 0 normal exit
  1408. * : -1 error exit
  1409. * input : irq
  1410. * : dev_id
  1411. * output : none
  1412. ******************************************************************************/
  1413. #ifndef TUNER_CONFIG_IRQ_PC_LINUX
  1414. irqreturn_t tuner_interrupt( int irq, void *dev_id )
  1415. #else /* TUNER_CONFIG_IRQ_PC_LINUX */
  1416. int tuner_interrupt( void )
  1417. #endif /* TUNER_CONFIG_IRQ_PC_LINUX */
  1418. {
  1419. DEBUG_PRINT("tuner_interrupt start ");
  1420. g_tuner_kthread_flag |= TUNER_KTH_IRQHANDLER;
  1421. if( waitqueue_active( &g_tuner_kthread_wait_queue ))
  1422. {
  1423. #ifdef TUNER_CONFIG_IRQ_LEVELTRIGGER
  1424. tuner_drv_disable_interrupt();
  1425. #endif /* TUNER_CONFIG_IRQ_LEVELTRIGGER */
  1426. wake_up( &g_tuner_kthread_wait_queue );
  1427. }
  1428. else
  1429. {
  1430. DEBUG_PRINT("tuner_interrupt waitqueue_active err!!! ");
  1431. }
  1432. DEBUG_PRINT("tuner_interrupt end ");
  1433. return IRQ_HANDLED;
  1434. }
  1435. MODULE_AUTHOR("Samsung");
  1436. MODULE_DESCRIPTION("MM Tuner Driver");
  1437. MODULE_LICENSE("GPL v2");