smscoreapi.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652
  1. /*
  2. * Siano core API module
  3. *
  4. * This file contains implementation for the interface to sms core component
  5. *
  6. * author: Uri Shkolnik
  7. *
  8. * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation;
  13. *
  14. * Software distributed under the License is distributed on an "AS IS"
  15. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  16. *
  17. * See the GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. */
  23. #include <linux/kernel.h>
  24. #include <linux/init.h>
  25. #include <linux/module.h>
  26. #include <linux/moduleparam.h>
  27. #include <linux/dma-mapping.h>
  28. #include <linux/delay.h>
  29. #include <linux/io.h>
  30. #include <linux/slab.h>
  31. #include <linux/firmware.h>
  32. #include <linux/wait.h>
  33. #include <asm/byteorder.h>
  34. #include "smscoreapi.h"
  35. #include "sms-cards.h"
  36. #include "smsir.h"
  37. #include "smsendian.h"
  38. static int sms_dbg;
  39. module_param_named(debug, sms_dbg, int, 0644);
  40. MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
  41. struct smscore_device_notifyee_t {
  42. struct list_head entry;
  43. hotplug_t hotplug;
  44. };
  45. struct smscore_idlist_t {
  46. struct list_head entry;
  47. int id;
  48. int data_type;
  49. };
  50. struct smscore_client_t {
  51. struct list_head entry;
  52. struct smscore_device_t *coredev;
  53. void *context;
  54. struct list_head idlist;
  55. onresponse_t onresponse_handler;
  56. onremove_t onremove_handler;
  57. };
  58. void smscore_set_board_id(struct smscore_device_t *core, int id)
  59. {
  60. core->board_id = id;
  61. }
  62. int smscore_led_state(struct smscore_device_t *core, int led)
  63. {
  64. if (led >= 0)
  65. core->led_state = led;
  66. return core->led_state;
  67. }
  68. EXPORT_SYMBOL_GPL(smscore_set_board_id);
  69. int smscore_get_board_id(struct smscore_device_t *core)
  70. {
  71. return core->board_id;
  72. }
  73. EXPORT_SYMBOL_GPL(smscore_get_board_id);
  74. struct smscore_registry_entry_t {
  75. struct list_head entry;
  76. char devpath[32];
  77. int mode;
  78. enum sms_device_type_st type;
  79. };
  80. static struct list_head g_smscore_notifyees;
  81. static struct list_head g_smscore_devices;
  82. static struct mutex g_smscore_deviceslock;
  83. static struct list_head g_smscore_registry;
  84. static struct mutex g_smscore_registrylock;
  85. static int default_mode = 4;
  86. module_param(default_mode, int, 0644);
  87. MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
  88. static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
  89. {
  90. struct smscore_registry_entry_t *entry;
  91. struct list_head *next;
  92. kmutex_lock(&g_smscore_registrylock);
  93. for (next = g_smscore_registry.next;
  94. next != &g_smscore_registry;
  95. next = next->next) {
  96. entry = (struct smscore_registry_entry_t *) next;
  97. if (!strcmp(entry->devpath, devpath)) {
  98. kmutex_unlock(&g_smscore_registrylock);
  99. return entry;
  100. }
  101. }
  102. entry = (struct smscore_registry_entry_t *)
  103. kmalloc(sizeof(struct smscore_registry_entry_t),
  104. GFP_KERNEL);
  105. if (entry) {
  106. entry->mode = default_mode;
  107. strcpy(entry->devpath, devpath);
  108. list_add(&entry->entry, &g_smscore_registry);
  109. } else
  110. sms_err("failed to create smscore_registry.");
  111. kmutex_unlock(&g_smscore_registrylock);
  112. return entry;
  113. }
  114. int smscore_registry_getmode(char *devpath)
  115. {
  116. struct smscore_registry_entry_t *entry;
  117. entry = smscore_find_registry(devpath);
  118. if (entry)
  119. return entry->mode;
  120. else
  121. sms_err("No registry found.");
  122. return default_mode;
  123. }
  124. EXPORT_SYMBOL_GPL(smscore_registry_getmode);
  125. static enum sms_device_type_st smscore_registry_gettype(char *devpath)
  126. {
  127. struct smscore_registry_entry_t *entry;
  128. entry = smscore_find_registry(devpath);
  129. if (entry)
  130. return entry->type;
  131. else
  132. sms_err("No registry found.");
  133. return -1;
  134. }
  135. void smscore_registry_setmode(char *devpath, int mode)
  136. {
  137. struct smscore_registry_entry_t *entry;
  138. entry = smscore_find_registry(devpath);
  139. if (entry)
  140. entry->mode = mode;
  141. else
  142. sms_err("No registry found.");
  143. }
  144. static void smscore_registry_settype(char *devpath,
  145. enum sms_device_type_st type)
  146. {
  147. struct smscore_registry_entry_t *entry;
  148. entry = smscore_find_registry(devpath);
  149. if (entry)
  150. entry->type = type;
  151. else
  152. sms_err("No registry found.");
  153. }
  154. static void list_add_locked(struct list_head *new, struct list_head *head,
  155. spinlock_t *lock)
  156. {
  157. unsigned long flags;
  158. spin_lock_irqsave(lock, flags);
  159. list_add(new, head);
  160. spin_unlock_irqrestore(lock, flags);
  161. }
  162. /**
  163. * register a client callback that called when device plugged in/unplugged
  164. * NOTE: if devices exist callback is called immediately for each device
  165. *
  166. * @param hotplug callback
  167. *
  168. * @return 0 on success, <0 on error.
  169. */
  170. int smscore_register_hotplug(hotplug_t hotplug)
  171. {
  172. struct smscore_device_notifyee_t *notifyee;
  173. struct list_head *next, *first;
  174. int rc = 0;
  175. kmutex_lock(&g_smscore_deviceslock);
  176. notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
  177. GFP_KERNEL);
  178. if (notifyee) {
  179. /* now notify callback about existing devices */
  180. first = &g_smscore_devices;
  181. for (next = first->next;
  182. next != first && !rc;
  183. next = next->next) {
  184. struct smscore_device_t *coredev =
  185. (struct smscore_device_t *) next;
  186. rc = hotplug(coredev, coredev->device, 1);
  187. }
  188. if (rc >= 0) {
  189. notifyee->hotplug = hotplug;
  190. list_add(&notifyee->entry, &g_smscore_notifyees);
  191. } else
  192. kfree(notifyee);
  193. } else
  194. rc = -ENOMEM;
  195. kmutex_unlock(&g_smscore_deviceslock);
  196. return rc;
  197. }
  198. EXPORT_SYMBOL_GPL(smscore_register_hotplug);
  199. /**
  200. * unregister a client callback that called when device plugged in/unplugged
  201. *
  202. * @param hotplug callback
  203. *
  204. */
  205. void smscore_unregister_hotplug(hotplug_t hotplug)
  206. {
  207. struct list_head *next, *first;
  208. kmutex_lock(&g_smscore_deviceslock);
  209. first = &g_smscore_notifyees;
  210. for (next = first->next; next != first;) {
  211. struct smscore_device_notifyee_t *notifyee =
  212. (struct smscore_device_notifyee_t *) next;
  213. next = next->next;
  214. if (notifyee->hotplug == hotplug) {
  215. list_del(&notifyee->entry);
  216. kfree(notifyee);
  217. }
  218. }
  219. kmutex_unlock(&g_smscore_deviceslock);
  220. }
  221. EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
  222. static void smscore_notify_clients(struct smscore_device_t *coredev)
  223. {
  224. struct smscore_client_t *client;
  225. /* the client must call smscore_unregister_client from remove handler */
  226. while (!list_empty(&coredev->clients)) {
  227. client = (struct smscore_client_t *) coredev->clients.next;
  228. client->onremove_handler(client->context);
  229. }
  230. }
  231. static int smscore_notify_callbacks(struct smscore_device_t *coredev,
  232. struct device *device, int arrival)
  233. {
  234. struct list_head *next, *first;
  235. int rc = 0;
  236. /* note: must be called under g_deviceslock */
  237. first = &g_smscore_notifyees;
  238. for (next = first->next; next != first; next = next->next) {
  239. rc = ((struct smscore_device_notifyee_t *) next)->
  240. hotplug(coredev, device, arrival);
  241. if (rc < 0)
  242. break;
  243. }
  244. return rc;
  245. }
  246. static struct
  247. smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
  248. dma_addr_t common_buffer_phys)
  249. {
  250. struct smscore_buffer_t *cb =
  251. kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
  252. if (!cb) {
  253. sms_info("kmalloc(...) failed");
  254. return NULL;
  255. }
  256. cb->p = buffer;
  257. cb->offset_in_common = buffer - (u8 *) common_buffer;
  258. cb->phys = common_buffer_phys + cb->offset_in_common;
  259. return cb;
  260. }
  261. /**
  262. * creates coredev object for a device, prepares buffers,
  263. * creates buffer mappings, notifies registered hotplugs about new device.
  264. *
  265. * @param params device pointer to struct with device specific parameters
  266. * and handlers
  267. * @param coredev pointer to a value that receives created coredev object
  268. *
  269. * @return 0 on success, <0 on error.
  270. */
  271. int smscore_register_device(struct smsdevice_params_t *params,
  272. struct smscore_device_t **coredev)
  273. {
  274. struct smscore_device_t *dev;
  275. u8 *buffer;
  276. dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
  277. if (!dev) {
  278. sms_info("kzalloc(...) failed");
  279. return -ENOMEM;
  280. }
  281. /* init list entry so it could be safe in smscore_unregister_device */
  282. INIT_LIST_HEAD(&dev->entry);
  283. /* init queues */
  284. INIT_LIST_HEAD(&dev->clients);
  285. INIT_LIST_HEAD(&dev->buffers);
  286. /* init locks */
  287. spin_lock_init(&dev->clientslock);
  288. spin_lock_init(&dev->bufferslock);
  289. /* init completion events */
  290. init_completion(&dev->version_ex_done);
  291. init_completion(&dev->data_download_done);
  292. init_completion(&dev->trigger_done);
  293. init_completion(&dev->init_device_done);
  294. init_completion(&dev->reload_start_done);
  295. init_completion(&dev->resume_done);
  296. init_completion(&dev->gpio_configuration_done);
  297. init_completion(&dev->gpio_set_level_done);
  298. init_completion(&dev->gpio_get_level_done);
  299. init_completion(&dev->ir_init_done);
  300. /* Buffer management */
  301. init_waitqueue_head(&dev->buffer_mng_waitq);
  302. /* alloc common buffer */
  303. dev->common_buffer_size = params->buffer_size * params->num_buffers;
  304. dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
  305. &dev->common_buffer_phys,
  306. GFP_KERNEL | GFP_DMA);
  307. if (!dev->common_buffer) {
  308. smscore_unregister_device(dev);
  309. return -ENOMEM;
  310. }
  311. /* prepare dma buffers */
  312. for (buffer = dev->common_buffer;
  313. dev->num_buffers < params->num_buffers;
  314. dev->num_buffers++, buffer += params->buffer_size) {
  315. struct smscore_buffer_t *cb =
  316. smscore_createbuffer(buffer, dev->common_buffer,
  317. dev->common_buffer_phys);
  318. if (!cb) {
  319. smscore_unregister_device(dev);
  320. return -ENOMEM;
  321. }
  322. smscore_putbuffer(dev, cb);
  323. }
  324. sms_info("allocated %d buffers", dev->num_buffers);
  325. dev->mode = DEVICE_MODE_NONE;
  326. dev->context = params->context;
  327. dev->device = params->device;
  328. dev->setmode_handler = params->setmode_handler;
  329. dev->detectmode_handler = params->detectmode_handler;
  330. dev->sendrequest_handler = params->sendrequest_handler;
  331. dev->preload_handler = params->preload_handler;
  332. dev->postload_handler = params->postload_handler;
  333. dev->device_flags = params->flags;
  334. strcpy(dev->devpath, params->devpath);
  335. smscore_registry_settype(dev->devpath, params->device_type);
  336. /* add device to devices list */
  337. kmutex_lock(&g_smscore_deviceslock);
  338. list_add(&dev->entry, &g_smscore_devices);
  339. kmutex_unlock(&g_smscore_deviceslock);
  340. *coredev = dev;
  341. sms_info("device %p created", dev);
  342. return 0;
  343. }
  344. EXPORT_SYMBOL_GPL(smscore_register_device);
  345. static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
  346. void *buffer, size_t size, struct completion *completion) {
  347. int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
  348. if (rc < 0) {
  349. sms_info("sendrequest returned error %d", rc);
  350. return rc;
  351. }
  352. return wait_for_completion_timeout(completion,
  353. msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
  354. 0 : -ETIME;
  355. }
  356. /**
  357. * Starts & enables IR operations
  358. *
  359. * @return 0 on success, < 0 on error.
  360. */
  361. static int smscore_init_ir(struct smscore_device_t *coredev)
  362. {
  363. int ir_io;
  364. int rc;
  365. void *buffer;
  366. coredev->ir.input_dev = NULL;
  367. ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
  368. if (ir_io) {/* only if IR port exist we use IR sub-module */
  369. sms_info("IR loading");
  370. rc = sms_ir_init(coredev);
  371. if (rc != 0)
  372. sms_err("Error initialization DTV IR sub-module");
  373. else {
  374. buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
  375. SMS_DMA_ALIGNMENT,
  376. GFP_KERNEL | GFP_DMA);
  377. if (buffer) {
  378. struct SmsMsgData_ST2 *msg =
  379. (struct SmsMsgData_ST2 *)
  380. SMS_ALIGN_ADDRESS(buffer);
  381. SMS_INIT_MSG(&msg->xMsgHeader,
  382. MSG_SMS_START_IR_REQ,
  383. sizeof(struct SmsMsgData_ST2));
  384. msg->msgData[0] = coredev->ir.controller;
  385. msg->msgData[1] = coredev->ir.timeout;
  386. smsendian_handle_tx_message(
  387. (struct SmsMsgHdr_ST2 *)msg);
  388. rc = smscore_sendrequest_and_wait(coredev, msg,
  389. msg->xMsgHeader. msgLength,
  390. &coredev->ir_init_done);
  391. kfree(buffer);
  392. } else
  393. sms_err
  394. ("Sending IR initialization message failed");
  395. }
  396. } else
  397. sms_info("IR port has not been detected");
  398. return 0;
  399. }
  400. /**
  401. * sets initial device mode and notifies client hotplugs that device is ready
  402. *
  403. * @param coredev pointer to a coredev object returned by
  404. * smscore_register_device
  405. *
  406. * @return 0 on success, <0 on error.
  407. */
  408. int smscore_start_device(struct smscore_device_t *coredev)
  409. {
  410. int rc = smscore_set_device_mode(
  411. coredev, smscore_registry_getmode(coredev->devpath));
  412. if (rc < 0) {
  413. sms_info("set device mode faile , rc %d", rc);
  414. return rc;
  415. }
  416. kmutex_lock(&g_smscore_deviceslock);
  417. rc = smscore_notify_callbacks(coredev, coredev->device, 1);
  418. smscore_init_ir(coredev);
  419. sms_info("device %p started, rc %d", coredev, rc);
  420. kmutex_unlock(&g_smscore_deviceslock);
  421. return rc;
  422. }
  423. EXPORT_SYMBOL_GPL(smscore_start_device);
  424. static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
  425. void *buffer, size_t size)
  426. {
  427. struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
  428. struct SmsMsgHdr_ST *msg;
  429. u32 mem_address;
  430. u8 *payload = firmware->Payload;
  431. int rc = 0;
  432. firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
  433. firmware->Length = le32_to_cpu(firmware->Length);
  434. mem_address = firmware->StartAddress;
  435. sms_info("loading FW to addr 0x%x size %d",
  436. mem_address, firmware->Length);
  437. if (coredev->preload_handler) {
  438. rc = coredev->preload_handler(coredev->context);
  439. if (rc < 0)
  440. return rc;
  441. }
  442. /* PAGE_SIZE buffer shall be enough and dma aligned */
  443. msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
  444. if (!msg)
  445. return -ENOMEM;
  446. if (coredev->mode != DEVICE_MODE_NONE) {
  447. sms_debug("sending reload command.");
  448. SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
  449. sizeof(struct SmsMsgHdr_ST));
  450. rc = smscore_sendrequest_and_wait(coredev, msg,
  451. msg->msgLength,
  452. &coredev->reload_start_done);
  453. mem_address = *(u32 *) &payload[20];
  454. }
  455. while (size && rc >= 0) {
  456. struct SmsDataDownload_ST *DataMsg =
  457. (struct SmsDataDownload_ST *) msg;
  458. int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
  459. SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
  460. (u16)(sizeof(struct SmsMsgHdr_ST) +
  461. sizeof(u32) + payload_size));
  462. DataMsg->MemAddr = mem_address;
  463. memcpy(DataMsg->Payload, payload, payload_size);
  464. if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
  465. (coredev->mode == DEVICE_MODE_NONE))
  466. rc = coredev->sendrequest_handler(
  467. coredev->context, DataMsg,
  468. DataMsg->xMsgHeader.msgLength);
  469. else
  470. rc = smscore_sendrequest_and_wait(
  471. coredev, DataMsg,
  472. DataMsg->xMsgHeader.msgLength,
  473. &coredev->data_download_done);
  474. payload += payload_size;
  475. size -= payload_size;
  476. mem_address += payload_size;
  477. }
  478. if (rc >= 0) {
  479. if (coredev->mode == DEVICE_MODE_NONE) {
  480. struct SmsMsgData_ST *TriggerMsg =
  481. (struct SmsMsgData_ST *) msg;
  482. SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
  483. sizeof(struct SmsMsgHdr_ST) +
  484. sizeof(u32) * 5);
  485. TriggerMsg->msgData[0] = firmware->StartAddress;
  486. /* Entry point */
  487. TriggerMsg->msgData[1] = 5; /* Priority */
  488. TriggerMsg->msgData[2] = 0x200; /* Stack size */
  489. TriggerMsg->msgData[3] = 0; /* Parameter */
  490. TriggerMsg->msgData[4] = 4; /* Task ID */
  491. if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
  492. rc = coredev->sendrequest_handler(
  493. coredev->context, TriggerMsg,
  494. TriggerMsg->xMsgHeader.msgLength);
  495. msleep(100);
  496. } else
  497. rc = smscore_sendrequest_and_wait(
  498. coredev, TriggerMsg,
  499. TriggerMsg->xMsgHeader.msgLength,
  500. &coredev->trigger_done);
  501. } else {
  502. SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
  503. sizeof(struct SmsMsgHdr_ST));
  504. rc = coredev->sendrequest_handler(coredev->context,
  505. msg, msg->msgLength);
  506. }
  507. msleep(500);
  508. }
  509. sms_debug("rc=%d, postload=%p ", rc,
  510. coredev->postload_handler);
  511. kfree(msg);
  512. return ((rc >= 0) && coredev->postload_handler) ?
  513. coredev->postload_handler(coredev->context) :
  514. rc;
  515. }
  516. /**
  517. * loads specified firmware into a buffer and calls device loadfirmware_handler
  518. *
  519. * @param coredev pointer to a coredev object returned by
  520. * smscore_register_device
  521. * @param filename null-terminated string specifies firmware file name
  522. * @param loadfirmware_handler device handler that loads firmware
  523. *
  524. * @return 0 on success, <0 on error.
  525. */
  526. static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
  527. char *filename,
  528. loadfirmware_t loadfirmware_handler)
  529. {
  530. int rc = -ENOENT;
  531. const struct firmware *fw;
  532. u8 *fw_buffer;
  533. if (loadfirmware_handler == NULL && !(coredev->device_flags &
  534. SMS_DEVICE_FAMILY2))
  535. return -EINVAL;
  536. rc = request_firmware(&fw, filename, coredev->device);
  537. if (rc < 0) {
  538. sms_info("failed to open \"%s\"", filename);
  539. return rc;
  540. }
  541. sms_info("read FW %s, size=%zd", filename, fw->size);
  542. fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
  543. GFP_KERNEL | GFP_DMA);
  544. if (fw_buffer) {
  545. memcpy(fw_buffer, fw->data, fw->size);
  546. rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
  547. smscore_load_firmware_family2(coredev,
  548. fw_buffer,
  549. fw->size) :
  550. loadfirmware_handler(coredev->context,
  551. fw_buffer, fw->size);
  552. kfree(fw_buffer);
  553. } else {
  554. sms_info("failed to allocate firmware buffer");
  555. rc = -ENOMEM;
  556. }
  557. release_firmware(fw);
  558. return rc;
  559. }
  560. /**
  561. * notifies all clients registered with the device, notifies hotplugs,
  562. * frees all buffers and coredev object
  563. *
  564. * @param coredev pointer to a coredev object returned by
  565. * smscore_register_device
  566. *
  567. * @return 0 on success, <0 on error.
  568. */
  569. void smscore_unregister_device(struct smscore_device_t *coredev)
  570. {
  571. struct smscore_buffer_t *cb;
  572. int num_buffers = 0;
  573. int retry = 0;
  574. kmutex_lock(&g_smscore_deviceslock);
  575. /* Release input device (IR) resources */
  576. sms_ir_exit(coredev);
  577. smscore_notify_clients(coredev);
  578. smscore_notify_callbacks(coredev, NULL, 0);
  579. /* at this point all buffers should be back
  580. * onresponse must no longer be called */
  581. while (1) {
  582. while (!list_empty(&coredev->buffers)) {
  583. cb = (struct smscore_buffer_t *) coredev->buffers.next;
  584. list_del(&cb->entry);
  585. kfree(cb);
  586. num_buffers++;
  587. }
  588. if (num_buffers == coredev->num_buffers)
  589. break;
  590. if (++retry > 10) {
  591. sms_info("exiting although "
  592. "not all buffers released.");
  593. break;
  594. }
  595. sms_info("waiting for %d buffer(s)",
  596. coredev->num_buffers - num_buffers);
  597. msleep(100);
  598. }
  599. sms_info("freed %d buffers", num_buffers);
  600. if (coredev->common_buffer)
  601. dma_free_coherent(NULL, coredev->common_buffer_size,
  602. coredev->common_buffer, coredev->common_buffer_phys);
  603. if (coredev->fw_buf != NULL)
  604. kfree(coredev->fw_buf);
  605. list_del(&coredev->entry);
  606. kfree(coredev);
  607. kmutex_unlock(&g_smscore_deviceslock);
  608. sms_info("device %p destroyed", coredev);
  609. }
  610. EXPORT_SYMBOL_GPL(smscore_unregister_device);
  611. static int smscore_detect_mode(struct smscore_device_t *coredev)
  612. {
  613. void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
  614. GFP_KERNEL | GFP_DMA);
  615. struct SmsMsgHdr_ST *msg =
  616. (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
  617. int rc;
  618. if (!buffer)
  619. return -ENOMEM;
  620. SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
  621. sizeof(struct SmsMsgHdr_ST));
  622. rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
  623. &coredev->version_ex_done);
  624. if (rc == -ETIME) {
  625. sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
  626. if (wait_for_completion_timeout(&coredev->resume_done,
  627. msecs_to_jiffies(5000))) {
  628. rc = smscore_sendrequest_and_wait(
  629. coredev, msg, msg->msgLength,
  630. &coredev->version_ex_done);
  631. if (rc < 0)
  632. sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
  633. "second try, rc %d", rc);
  634. } else
  635. rc = -ETIME;
  636. }
  637. kfree(buffer);
  638. return rc;
  639. }
  640. static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
  641. /*Stellar NOVA A0 Nova B0 VEGA*/
  642. /*DVBT*/
  643. {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
  644. /*DVBH*/
  645. {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
  646. /*TDMB*/
  647. {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
  648. /*DABIP*/
  649. {"none", "none", "none", "none"},
  650. /*BDA*/
  651. {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
  652. /*ISDBT*/
  653. {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
  654. /*ISDBTBDA*/
  655. {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
  656. /*CMMB*/
  657. {"none", "none", "none", "cmmb_vega_12mhz.inp"}
  658. };
  659. static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
  660. int mode, enum sms_device_type_st type)
  661. {
  662. char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
  663. return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
  664. }
  665. /**
  666. * calls device handler to change mode of operation
  667. * NOTE: stellar/usb may disconnect when changing mode
  668. *
  669. * @param coredev pointer to a coredev object returned by
  670. * smscore_register_device
  671. * @param mode requested mode of operation
  672. *
  673. * @return 0 on success, <0 on error.
  674. */
  675. int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
  676. {
  677. void *buffer;
  678. int rc = 0;
  679. enum sms_device_type_st type;
  680. sms_debug("set device mode to %d", mode);
  681. if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
  682. if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
  683. sms_err("invalid mode specified %d", mode);
  684. return -EINVAL;
  685. }
  686. smscore_registry_setmode(coredev->devpath, mode);
  687. if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
  688. rc = smscore_detect_mode(coredev);
  689. if (rc < 0) {
  690. sms_err("mode detect failed %d", rc);
  691. return rc;
  692. }
  693. }
  694. if (coredev->mode == mode) {
  695. sms_info("device mode %d already set", mode);
  696. return 0;
  697. }
  698. if (!(coredev->modes_supported & (1 << mode))) {
  699. char *fw_filename;
  700. type = smscore_registry_gettype(coredev->devpath);
  701. fw_filename = sms_get_fw_name(coredev, mode, type);
  702. rc = smscore_load_firmware_from_file(coredev,
  703. fw_filename, NULL);
  704. if (rc < 0) {
  705. sms_warn("error %d loading firmware: %s, "
  706. "trying again with default firmware",
  707. rc, fw_filename);
  708. /* try again with the default firmware */
  709. fw_filename = smscore_fw_lkup[mode][type];
  710. rc = smscore_load_firmware_from_file(coredev,
  711. fw_filename, NULL);
  712. if (rc < 0) {
  713. sms_warn("error %d loading "
  714. "firmware: %s", rc,
  715. fw_filename);
  716. return rc;
  717. }
  718. }
  719. sms_log("firmware download success: %s", fw_filename);
  720. } else
  721. sms_info("mode %d supported by running "
  722. "firmware", mode);
  723. buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
  724. SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
  725. if (buffer) {
  726. struct SmsMsgData_ST *msg =
  727. (struct SmsMsgData_ST *)
  728. SMS_ALIGN_ADDRESS(buffer);
  729. SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
  730. sizeof(struct SmsMsgData_ST));
  731. msg->msgData[0] = mode;
  732. rc = smscore_sendrequest_and_wait(
  733. coredev, msg, msg->xMsgHeader.msgLength,
  734. &coredev->init_device_done);
  735. kfree(buffer);
  736. } else {
  737. sms_err("Could not allocate buffer for "
  738. "init device message.");
  739. rc = -ENOMEM;
  740. }
  741. } else {
  742. if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
  743. sms_err("invalid mode specified %d", mode);
  744. return -EINVAL;
  745. }
  746. smscore_registry_setmode(coredev->devpath, mode);
  747. if (coredev->detectmode_handler)
  748. coredev->detectmode_handler(coredev->context,
  749. &coredev->mode);
  750. if (coredev->mode != mode && coredev->setmode_handler)
  751. rc = coredev->setmode_handler(coredev->context, mode);
  752. }
  753. if (rc >= 0) {
  754. coredev->mode = mode;
  755. coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
  756. }
  757. if (rc < 0)
  758. sms_err("return error code %d.", rc);
  759. return rc;
  760. }
  761. /**
  762. * calls device handler to get current mode of operation
  763. *
  764. * @param coredev pointer to a coredev object returned by
  765. * smscore_register_device
  766. *
  767. * @return current mode
  768. */
  769. int smscore_get_device_mode(struct smscore_device_t *coredev)
  770. {
  771. return coredev->mode;
  772. }
  773. EXPORT_SYMBOL_GPL(smscore_get_device_mode);
  774. /**
  775. * find client by response id & type within the clients list.
  776. * return client handle or NULL.
  777. *
  778. * @param coredev pointer to a coredev object returned by
  779. * smscore_register_device
  780. * @param data_type client data type (SMS_DONT_CARE for all types)
  781. * @param id client id (SMS_DONT_CARE for all id)
  782. *
  783. */
  784. static struct
  785. smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
  786. int data_type, int id)
  787. {
  788. struct smscore_client_t *client = NULL;
  789. struct list_head *next, *first;
  790. unsigned long flags;
  791. struct list_head *firstid, *nextid;
  792. spin_lock_irqsave(&coredev->clientslock, flags);
  793. first = &coredev->clients;
  794. for (next = first->next;
  795. (next != first) && !client;
  796. next = next->next) {
  797. firstid = &((struct smscore_client_t *)next)->idlist;
  798. for (nextid = firstid->next;
  799. nextid != firstid;
  800. nextid = nextid->next) {
  801. if ((((struct smscore_idlist_t *)nextid)->id == id) &&
  802. (((struct smscore_idlist_t *)nextid)->data_type == data_type ||
  803. (((struct smscore_idlist_t *)nextid)->data_type == 0))) {
  804. client = (struct smscore_client_t *) next;
  805. break;
  806. }
  807. }
  808. }
  809. spin_unlock_irqrestore(&coredev->clientslock, flags);
  810. return client;
  811. }
  812. /**
  813. * find client by response id/type, call clients onresponse handler
  814. * return buffer to pool on error
  815. *
  816. * @param coredev pointer to a coredev object returned by
  817. * smscore_register_device
  818. * @param cb pointer to response buffer descriptor
  819. *
  820. */
  821. void smscore_onresponse(struct smscore_device_t *coredev,
  822. struct smscore_buffer_t *cb) {
  823. struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
  824. + cb->offset);
  825. struct smscore_client_t *client;
  826. int rc = -EBUSY;
  827. static unsigned long last_sample_time; /* = 0; */
  828. static int data_total; /* = 0; */
  829. unsigned long time_now = jiffies_to_msecs(jiffies);
  830. if (!last_sample_time)
  831. last_sample_time = time_now;
  832. if (time_now - last_sample_time > 10000) {
  833. sms_debug("\ndata rate %d bytes/secs",
  834. (int)((data_total * 1000) /
  835. (time_now - last_sample_time)));
  836. last_sample_time = time_now;
  837. data_total = 0;
  838. }
  839. data_total += cb->size;
  840. /* Do we need to re-route? */
  841. if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
  842. (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
  843. if (coredev->mode == DEVICE_MODE_DVBT_BDA)
  844. phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
  845. }
  846. client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
  847. /* If no client registered for type & id,
  848. * check for control client where type is not registered */
  849. if (client)
  850. rc = client->onresponse_handler(client->context, cb);
  851. if (rc < 0) {
  852. switch (phdr->msgType) {
  853. case MSG_SMS_GET_VERSION_EX_RES:
  854. {
  855. struct SmsVersionRes_ST *ver =
  856. (struct SmsVersionRes_ST *) phdr;
  857. sms_debug("MSG_SMS_GET_VERSION_EX_RES "
  858. "id %d prots 0x%x ver %d.%d",
  859. ver->FirmwareId, ver->SupportedProtocols,
  860. ver->RomVersionMajor, ver->RomVersionMinor);
  861. coredev->mode = ver->FirmwareId == 255 ?
  862. DEVICE_MODE_NONE : ver->FirmwareId;
  863. coredev->modes_supported = ver->SupportedProtocols;
  864. complete(&coredev->version_ex_done);
  865. break;
  866. }
  867. case MSG_SMS_INIT_DEVICE_RES:
  868. sms_debug("MSG_SMS_INIT_DEVICE_RES");
  869. complete(&coredev->init_device_done);
  870. break;
  871. case MSG_SW_RELOAD_START_RES:
  872. sms_debug("MSG_SW_RELOAD_START_RES");
  873. complete(&coredev->reload_start_done);
  874. break;
  875. case MSG_SMS_DATA_DOWNLOAD_RES:
  876. complete(&coredev->data_download_done);
  877. break;
  878. case MSG_SW_RELOAD_EXEC_RES:
  879. sms_debug("MSG_SW_RELOAD_EXEC_RES");
  880. break;
  881. case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
  882. sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
  883. complete(&coredev->trigger_done);
  884. break;
  885. case MSG_SMS_SLEEP_RESUME_COMP_IND:
  886. complete(&coredev->resume_done);
  887. break;
  888. case MSG_SMS_GPIO_CONFIG_EX_RES:
  889. sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
  890. complete(&coredev->gpio_configuration_done);
  891. break;
  892. case MSG_SMS_GPIO_SET_LEVEL_RES:
  893. sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
  894. complete(&coredev->gpio_set_level_done);
  895. break;
  896. case MSG_SMS_GPIO_GET_LEVEL_RES:
  897. {
  898. u32 *msgdata = (u32 *) phdr;
  899. coredev->gpio_get_res = msgdata[1];
  900. sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
  901. coredev->gpio_get_res);
  902. complete(&coredev->gpio_get_level_done);
  903. break;
  904. }
  905. case MSG_SMS_START_IR_RES:
  906. complete(&coredev->ir_init_done);
  907. break;
  908. case MSG_SMS_IR_SAMPLES_IND:
  909. sms_ir_event(coredev,
  910. (const char *)
  911. ((char *)phdr
  912. + sizeof(struct SmsMsgHdr_ST)),
  913. (int)phdr->msgLength
  914. - sizeof(struct SmsMsgHdr_ST));
  915. break;
  916. default:
  917. break;
  918. }
  919. smscore_putbuffer(coredev, cb);
  920. }
  921. }
  922. EXPORT_SYMBOL_GPL(smscore_onresponse);
  923. /**
  924. * return pointer to next free buffer descriptor from core pool
  925. *
  926. * @param coredev pointer to a coredev object returned by
  927. * smscore_register_device
  928. *
  929. * @return pointer to descriptor on success, NULL on error.
  930. */
  931. struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
  932. {
  933. struct smscore_buffer_t *cb = NULL;
  934. unsigned long flags;
  935. DEFINE_WAIT(wait);
  936. spin_lock_irqsave(&coredev->bufferslock, flags);
  937. /* This function must return a valid buffer, since the buffer list is
  938. * finite, we check that there is an available buffer, if not, we wait
  939. * until such buffer become available.
  940. */
  941. prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE);
  942. if (list_empty(&coredev->buffers))
  943. schedule();
  944. finish_wait(&coredev->buffer_mng_waitq, &wait);
  945. cb = (struct smscore_buffer_t *) coredev->buffers.next;
  946. list_del(&cb->entry);
  947. spin_unlock_irqrestore(&coredev->bufferslock, flags);
  948. return cb;
  949. }
  950. EXPORT_SYMBOL_GPL(smscore_getbuffer);
  951. /**
  952. * return buffer descriptor to a pool
  953. *
  954. * @param coredev pointer to a coredev object returned by
  955. * smscore_register_device
  956. * @param cb pointer buffer descriptor
  957. *
  958. */
  959. void smscore_putbuffer(struct smscore_device_t *coredev,
  960. struct smscore_buffer_t *cb) {
  961. wake_up_interruptible(&coredev->buffer_mng_waitq);
  962. list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
  963. }
  964. EXPORT_SYMBOL_GPL(smscore_putbuffer);
  965. static int smscore_validate_client(struct smscore_device_t *coredev,
  966. struct smscore_client_t *client,
  967. int data_type, int id)
  968. {
  969. struct smscore_idlist_t *listentry;
  970. struct smscore_client_t *registered_client;
  971. if (!client) {
  972. sms_err("bad parameter.");
  973. return -EFAULT;
  974. }
  975. registered_client = smscore_find_client(coredev, data_type, id);
  976. if (registered_client == client)
  977. return 0;
  978. if (registered_client) {
  979. sms_err("The msg ID already registered to another client.");
  980. return -EEXIST;
  981. }
  982. listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
  983. if (!listentry) {
  984. sms_err("Can't allocate memory for client id.");
  985. return -ENOMEM;
  986. }
  987. listentry->id = id;
  988. listentry->data_type = data_type;
  989. list_add_locked(&listentry->entry, &client->idlist,
  990. &coredev->clientslock);
  991. return 0;
  992. }
  993. /**
  994. * creates smsclient object, check that id is taken by another client
  995. *
  996. * @param coredev pointer to a coredev object from clients hotplug
  997. * @param initial_id all messages with this id would be sent to this client
  998. * @param data_type all messages of this type would be sent to this client
  999. * @param onresponse_handler client handler that is called to
  1000. * process incoming messages
  1001. * @param onremove_handler client handler that is called when device is removed
  1002. * @param context client-specific context
  1003. * @param client pointer to a value that receives created smsclient object
  1004. *
  1005. * @return 0 on success, <0 on error.
  1006. */
  1007. int smscore_register_client(struct smscore_device_t *coredev,
  1008. struct smsclient_params_t *params,
  1009. struct smscore_client_t **client)
  1010. {
  1011. struct smscore_client_t *newclient;
  1012. /* check that no other channel with same parameters exists */
  1013. if (smscore_find_client(coredev, params->data_type,
  1014. params->initial_id)) {
  1015. sms_err("Client already exist.");
  1016. return -EEXIST;
  1017. }
  1018. newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
  1019. if (!newclient) {
  1020. sms_err("Failed to allocate memory for client.");
  1021. return -ENOMEM;
  1022. }
  1023. INIT_LIST_HEAD(&newclient->idlist);
  1024. newclient->coredev = coredev;
  1025. newclient->onresponse_handler = params->onresponse_handler;
  1026. newclient->onremove_handler = params->onremove_handler;
  1027. newclient->context = params->context;
  1028. list_add_locked(&newclient->entry, &coredev->clients,
  1029. &coredev->clientslock);
  1030. smscore_validate_client(coredev, newclient, params->data_type,
  1031. params->initial_id);
  1032. *client = newclient;
  1033. sms_debug("%p %d %d", params->context, params->data_type,
  1034. params->initial_id);
  1035. return 0;
  1036. }
  1037. EXPORT_SYMBOL_GPL(smscore_register_client);
  1038. /**
  1039. * frees smsclient object and all subclients associated with it
  1040. *
  1041. * @param client pointer to smsclient object returned by
  1042. * smscore_register_client
  1043. *
  1044. */
  1045. void smscore_unregister_client(struct smscore_client_t *client)
  1046. {
  1047. struct smscore_device_t *coredev = client->coredev;
  1048. unsigned long flags;
  1049. spin_lock_irqsave(&coredev->clientslock, flags);
  1050. while (!list_empty(&client->idlist)) {
  1051. struct smscore_idlist_t *identry =
  1052. (struct smscore_idlist_t *) client->idlist.next;
  1053. list_del(&identry->entry);
  1054. kfree(identry);
  1055. }
  1056. sms_info("%p", client->context);
  1057. list_del(&client->entry);
  1058. kfree(client);
  1059. spin_unlock_irqrestore(&coredev->clientslock, flags);
  1060. }
  1061. EXPORT_SYMBOL_GPL(smscore_unregister_client);
  1062. /**
  1063. * verifies that source id is not taken by another client,
  1064. * calls device handler to send requests to the device
  1065. *
  1066. * @param client pointer to smsclient object returned by
  1067. * smscore_register_client
  1068. * @param buffer pointer to a request buffer
  1069. * @param size size (in bytes) of request buffer
  1070. *
  1071. * @return 0 on success, <0 on error.
  1072. */
  1073. int smsclient_sendrequest(struct smscore_client_t *client,
  1074. void *buffer, size_t size)
  1075. {
  1076. struct smscore_device_t *coredev;
  1077. struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
  1078. int rc;
  1079. if (client == NULL) {
  1080. sms_err("Got NULL client");
  1081. return -EINVAL;
  1082. }
  1083. coredev = client->coredev;
  1084. /* check that no other channel with same id exists */
  1085. if (coredev == NULL) {
  1086. sms_err("Got NULL coredev");
  1087. return -EINVAL;
  1088. }
  1089. rc = smscore_validate_client(client->coredev, client, 0,
  1090. phdr->msgSrcId);
  1091. if (rc < 0)
  1092. return rc;
  1093. return coredev->sendrequest_handler(coredev->context, buffer, size);
  1094. }
  1095. EXPORT_SYMBOL_GPL(smsclient_sendrequest);
  1096. /* old GPIO managments implementation */
  1097. int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
  1098. struct smscore_config_gpio *pinconfig)
  1099. {
  1100. struct {
  1101. struct SmsMsgHdr_ST hdr;
  1102. u32 data[6];
  1103. } msg;
  1104. if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
  1105. msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
  1106. msg.hdr.msgDstId = HIF_TASK;
  1107. msg.hdr.msgFlags = 0;
  1108. msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
  1109. msg.hdr.msgLength = sizeof(msg);
  1110. msg.data[0] = pin;
  1111. msg.data[1] = pinconfig->pullupdown;
  1112. /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
  1113. msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
  1114. switch (pinconfig->outputdriving) {
  1115. case SMS_GPIO_OUTPUTDRIVING_16mA:
  1116. msg.data[3] = 7; /* Nova - 16mA */
  1117. break;
  1118. case SMS_GPIO_OUTPUTDRIVING_12mA:
  1119. msg.data[3] = 5; /* Nova - 11mA */
  1120. break;
  1121. case SMS_GPIO_OUTPUTDRIVING_8mA:
  1122. msg.data[3] = 3; /* Nova - 7mA */
  1123. break;
  1124. case SMS_GPIO_OUTPUTDRIVING_4mA:
  1125. default:
  1126. msg.data[3] = 2; /* Nova - 4mA */
  1127. break;
  1128. }
  1129. msg.data[4] = pinconfig->direction;
  1130. msg.data[5] = 0;
  1131. } else /* TODO: SMS_DEVICE_FAMILY1 */
  1132. return -EINVAL;
  1133. return coredev->sendrequest_handler(coredev->context,
  1134. &msg, sizeof(msg));
  1135. }
  1136. int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
  1137. {
  1138. struct {
  1139. struct SmsMsgHdr_ST hdr;
  1140. u32 data[3];
  1141. } msg;
  1142. if (pin > MAX_GPIO_PIN_NUMBER)
  1143. return -EINVAL;
  1144. msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
  1145. msg.hdr.msgDstId = HIF_TASK;
  1146. msg.hdr.msgFlags = 0;
  1147. msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
  1148. msg.hdr.msgLength = sizeof(msg);
  1149. msg.data[0] = pin;
  1150. msg.data[1] = level ? 1 : 0;
  1151. msg.data[2] = 0;
  1152. return coredev->sendrequest_handler(coredev->context,
  1153. &msg, sizeof(msg));
  1154. }
  1155. /* new GPIO management implementation */
  1156. static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
  1157. u32 *pGroupNum, u32 *pGroupCfg) {
  1158. *pGroupCfg = 1;
  1159. if (PinNum <= 1) {
  1160. *pTranslatedPinNum = 0;
  1161. *pGroupNum = 9;
  1162. *pGroupCfg = 2;
  1163. } else if (PinNum >= 2 && PinNum <= 6) {
  1164. *pTranslatedPinNum = 2;
  1165. *pGroupNum = 0;
  1166. *pGroupCfg = 2;
  1167. } else if (PinNum >= 7 && PinNum <= 11) {
  1168. *pTranslatedPinNum = 7;
  1169. *pGroupNum = 1;
  1170. } else if (PinNum >= 12 && PinNum <= 15) {
  1171. *pTranslatedPinNum = 12;
  1172. *pGroupNum = 2;
  1173. *pGroupCfg = 3;
  1174. } else if (PinNum == 16) {
  1175. *pTranslatedPinNum = 16;
  1176. *pGroupNum = 23;
  1177. } else if (PinNum >= 17 && PinNum <= 24) {
  1178. *pTranslatedPinNum = 17;
  1179. *pGroupNum = 3;
  1180. } else if (PinNum == 25) {
  1181. *pTranslatedPinNum = 25;
  1182. *pGroupNum = 6;
  1183. } else if (PinNum >= 26 && PinNum <= 28) {
  1184. *pTranslatedPinNum = 26;
  1185. *pGroupNum = 4;
  1186. } else if (PinNum == 29) {
  1187. *pTranslatedPinNum = 29;
  1188. *pGroupNum = 5;
  1189. *pGroupCfg = 2;
  1190. } else if (PinNum == 30) {
  1191. *pTranslatedPinNum = 30;
  1192. *pGroupNum = 8;
  1193. } else if (PinNum == 31) {
  1194. *pTranslatedPinNum = 31;
  1195. *pGroupNum = 17;
  1196. } else
  1197. return -1;
  1198. *pGroupCfg <<= 24;
  1199. return 0;
  1200. }
  1201. int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
  1202. struct smscore_gpio_config *pGpioConfig) {
  1203. u32 totalLen;
  1204. u32 TranslatedPinNum = 0;
  1205. u32 GroupNum = 0;
  1206. u32 ElectricChar;
  1207. u32 groupCfg;
  1208. void *buffer;
  1209. int rc;
  1210. struct SetGpioMsg {
  1211. struct SmsMsgHdr_ST xMsgHeader;
  1212. u32 msgData[6];
  1213. } *pMsg;
  1214. if (PinNum > MAX_GPIO_PIN_NUMBER)
  1215. return -EINVAL;
  1216. if (pGpioConfig == NULL)
  1217. return -EINVAL;
  1218. totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
  1219. buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
  1220. GFP_KERNEL | GFP_DMA);
  1221. if (!buffer)
  1222. return -ENOMEM;
  1223. pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
  1224. pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
  1225. pMsg->xMsgHeader.msgDstId = HIF_TASK;
  1226. pMsg->xMsgHeader.msgFlags = 0;
  1227. pMsg->xMsgHeader.msgLength = (u16) totalLen;
  1228. pMsg->msgData[0] = PinNum;
  1229. if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
  1230. pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
  1231. if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
  1232. &groupCfg) != 0) {
  1233. rc = -EINVAL;
  1234. goto free;
  1235. }
  1236. pMsg->msgData[1] = TranslatedPinNum;
  1237. pMsg->msgData[2] = GroupNum;
  1238. ElectricChar = (pGpioConfig->PullUpDown)
  1239. | (pGpioConfig->InputCharacteristics << 2)
  1240. | (pGpioConfig->OutputSlewRate << 3)
  1241. | (pGpioConfig->OutputDriving << 4);
  1242. pMsg->msgData[3] = ElectricChar;
  1243. pMsg->msgData[4] = pGpioConfig->Direction;
  1244. pMsg->msgData[5] = groupCfg;
  1245. } else {
  1246. pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
  1247. pMsg->msgData[1] = pGpioConfig->PullUpDown;
  1248. pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
  1249. pMsg->msgData[3] = pGpioConfig->OutputDriving;
  1250. pMsg->msgData[4] = pGpioConfig->Direction;
  1251. pMsg->msgData[5] = 0;
  1252. }
  1253. smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
  1254. rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
  1255. &coredev->gpio_configuration_done);
  1256. if (rc != 0) {
  1257. if (rc == -ETIME)
  1258. sms_err("smscore_gpio_configure timeout");
  1259. else
  1260. sms_err("smscore_gpio_configure error");
  1261. }
  1262. free:
  1263. kfree(buffer);
  1264. return rc;
  1265. }
  1266. int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
  1267. u8 NewLevel) {
  1268. u32 totalLen;
  1269. int rc;
  1270. void *buffer;
  1271. struct SetGpioMsg {
  1272. struct SmsMsgHdr_ST xMsgHeader;
  1273. u32 msgData[3]; /* keep it 3 ! */
  1274. } *pMsg;
  1275. if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) ||
  1276. (PinNum > MAX_GPIO_PIN_NUMBER))
  1277. return -EINVAL;
  1278. totalLen = sizeof(struct SmsMsgHdr_ST) +
  1279. (3 * sizeof(u32)); /* keep it 3 ! */
  1280. buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
  1281. GFP_KERNEL | GFP_DMA);
  1282. if (!buffer)
  1283. return -ENOMEM;
  1284. pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
  1285. pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
  1286. pMsg->xMsgHeader.msgDstId = HIF_TASK;
  1287. pMsg->xMsgHeader.msgFlags = 0;
  1288. pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
  1289. pMsg->xMsgHeader.msgLength = (u16) totalLen;
  1290. pMsg->msgData[0] = PinNum;
  1291. pMsg->msgData[1] = NewLevel;
  1292. /* Send message to SMS */
  1293. smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
  1294. rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
  1295. &coredev->gpio_set_level_done);
  1296. if (rc != 0) {
  1297. if (rc == -ETIME)
  1298. sms_err("smscore_gpio_set_level timeout");
  1299. else
  1300. sms_err("smscore_gpio_set_level error");
  1301. }
  1302. kfree(buffer);
  1303. return rc;
  1304. }
  1305. int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
  1306. u8 *level) {
  1307. u32 totalLen;
  1308. int rc;
  1309. void *buffer;
  1310. struct SetGpioMsg {
  1311. struct SmsMsgHdr_ST xMsgHeader;
  1312. u32 msgData[2];
  1313. } *pMsg;
  1314. if (PinNum > MAX_GPIO_PIN_NUMBER)
  1315. return -EINVAL;
  1316. totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
  1317. buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
  1318. GFP_KERNEL | GFP_DMA);
  1319. if (!buffer)
  1320. return -ENOMEM;
  1321. pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
  1322. pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
  1323. pMsg->xMsgHeader.msgDstId = HIF_TASK;
  1324. pMsg->xMsgHeader.msgFlags = 0;
  1325. pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
  1326. pMsg->xMsgHeader.msgLength = (u16) totalLen;
  1327. pMsg->msgData[0] = PinNum;
  1328. pMsg->msgData[1] = 0;
  1329. /* Send message to SMS */
  1330. smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
  1331. rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
  1332. &coredev->gpio_get_level_done);
  1333. if (rc != 0) {
  1334. if (rc == -ETIME)
  1335. sms_err("smscore_gpio_get_level timeout");
  1336. else
  1337. sms_err("smscore_gpio_get_level error");
  1338. }
  1339. kfree(buffer);
  1340. /* Its a race between other gpio_get_level() and the copy of the single
  1341. * global 'coredev->gpio_get_res' to the function's variable 'level'
  1342. */
  1343. *level = coredev->gpio_get_res;
  1344. return rc;
  1345. }
  1346. static int __init smscore_module_init(void)
  1347. {
  1348. int rc = 0;
  1349. INIT_LIST_HEAD(&g_smscore_notifyees);
  1350. INIT_LIST_HEAD(&g_smscore_devices);
  1351. kmutex_init(&g_smscore_deviceslock);
  1352. INIT_LIST_HEAD(&g_smscore_registry);
  1353. kmutex_init(&g_smscore_registrylock);
  1354. return rc;
  1355. }
  1356. static void __exit smscore_module_exit(void)
  1357. {
  1358. kmutex_lock(&g_smscore_deviceslock);
  1359. while (!list_empty(&g_smscore_notifyees)) {
  1360. struct smscore_device_notifyee_t *notifyee =
  1361. (struct smscore_device_notifyee_t *)
  1362. g_smscore_notifyees.next;
  1363. list_del(&notifyee->entry);
  1364. kfree(notifyee);
  1365. }
  1366. kmutex_unlock(&g_smscore_deviceslock);
  1367. kmutex_lock(&g_smscore_registrylock);
  1368. while (!list_empty(&g_smscore_registry)) {
  1369. struct smscore_registry_entry_t *entry =
  1370. (struct smscore_registry_entry_t *)
  1371. g_smscore_registry.next;
  1372. list_del(&entry->entry);
  1373. kfree(entry);
  1374. }
  1375. kmutex_unlock(&g_smscore_registrylock);
  1376. sms_debug("");
  1377. }
  1378. module_init(smscore_module_init);
  1379. module_exit(smscore_module_exit);
  1380. MODULE_DESCRIPTION("Siano MDTV Core module");
  1381. MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
  1382. MODULE_LICENSE("GPL");