ctsrc.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. /**
  2. * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
  3. *
  4. * This source file is released under GPL v2 license (no other versions).
  5. * See the COPYING file included in the main directory of this source
  6. * distribution for the license terms and conditions.
  7. *
  8. * @File ctsrc.c
  9. *
  10. * @Brief
  11. * This file contains the implementation of the Sample Rate Convertor
  12. * resource management object.
  13. *
  14. * @Author Liu Chun
  15. * @Date May 13 2008
  16. *
  17. */
  18. #include "ctsrc.h"
  19. #include "cthardware.h"
  20. #include <linux/slab.h>
  21. #define SRC_RESOURCE_NUM 256
  22. #define SRCIMP_RESOURCE_NUM 256
  23. static unsigned int conj_mask;
  24. static int src_default_config_memrd(struct src *src);
  25. static int src_default_config_memwr(struct src *src);
  26. static int src_default_config_arcrw(struct src *src);
  27. static int (*src_default_config[3])(struct src *) = {
  28. [MEMRD] = src_default_config_memrd,
  29. [MEMWR] = src_default_config_memwr,
  30. [ARCRW] = src_default_config_arcrw
  31. };
  32. static int src_set_state(struct src *src, unsigned int state)
  33. {
  34. struct hw *hw;
  35. hw = src->rsc.hw;
  36. hw->src_set_state(src->rsc.ctrl_blk, state);
  37. return 0;
  38. }
  39. static int src_set_bm(struct src *src, unsigned int bm)
  40. {
  41. struct hw *hw;
  42. hw = src->rsc.hw;
  43. hw->src_set_bm(src->rsc.ctrl_blk, bm);
  44. return 0;
  45. }
  46. static int src_set_sf(struct src *src, unsigned int sf)
  47. {
  48. struct hw *hw;
  49. hw = src->rsc.hw;
  50. hw->src_set_sf(src->rsc.ctrl_blk, sf);
  51. return 0;
  52. }
  53. static int src_set_pm(struct src *src, unsigned int pm)
  54. {
  55. struct hw *hw;
  56. hw = src->rsc.hw;
  57. hw->src_set_pm(src->rsc.ctrl_blk, pm);
  58. return 0;
  59. }
  60. static int src_set_rom(struct src *src, unsigned int rom)
  61. {
  62. struct hw *hw;
  63. hw = src->rsc.hw;
  64. hw->src_set_rom(src->rsc.ctrl_blk, rom);
  65. return 0;
  66. }
  67. static int src_set_vo(struct src *src, unsigned int vo)
  68. {
  69. struct hw *hw;
  70. hw = src->rsc.hw;
  71. hw->src_set_vo(src->rsc.ctrl_blk, vo);
  72. return 0;
  73. }
  74. static int src_set_st(struct src *src, unsigned int st)
  75. {
  76. struct hw *hw;
  77. hw = src->rsc.hw;
  78. hw->src_set_st(src->rsc.ctrl_blk, st);
  79. return 0;
  80. }
  81. static int src_set_bp(struct src *src, unsigned int bp)
  82. {
  83. struct hw *hw;
  84. hw = src->rsc.hw;
  85. hw->src_set_bp(src->rsc.ctrl_blk, bp);
  86. return 0;
  87. }
  88. static int src_set_cisz(struct src *src, unsigned int cisz)
  89. {
  90. struct hw *hw;
  91. hw = src->rsc.hw;
  92. hw->src_set_cisz(src->rsc.ctrl_blk, cisz);
  93. return 0;
  94. }
  95. static int src_set_ca(struct src *src, unsigned int ca)
  96. {
  97. struct hw *hw;
  98. hw = src->rsc.hw;
  99. hw->src_set_ca(src->rsc.ctrl_blk, ca);
  100. return 0;
  101. }
  102. static int src_set_sa(struct src *src, unsigned int sa)
  103. {
  104. struct hw *hw;
  105. hw = src->rsc.hw;
  106. hw->src_set_sa(src->rsc.ctrl_blk, sa);
  107. return 0;
  108. }
  109. static int src_set_la(struct src *src, unsigned int la)
  110. {
  111. struct hw *hw;
  112. hw = src->rsc.hw;
  113. hw->src_set_la(src->rsc.ctrl_blk, la);
  114. return 0;
  115. }
  116. static int src_set_pitch(struct src *src, unsigned int pitch)
  117. {
  118. struct hw *hw;
  119. hw = src->rsc.hw;
  120. hw->src_set_pitch(src->rsc.ctrl_blk, pitch);
  121. return 0;
  122. }
  123. static int src_set_clear_zbufs(struct src *src)
  124. {
  125. struct hw *hw;
  126. hw = src->rsc.hw;
  127. hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
  128. return 0;
  129. }
  130. static int src_commit_write(struct src *src)
  131. {
  132. struct hw *hw;
  133. int i;
  134. unsigned int dirty = 0;
  135. hw = src->rsc.hw;
  136. src->rsc.ops->master(&src->rsc);
  137. if (src->rsc.msr > 1) {
  138. /* Save dirty flags for conjugate resource programming */
  139. dirty = hw->src_get_dirty(src->rsc.ctrl_blk) & conj_mask;
  140. }
  141. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  142. src->rsc.ctrl_blk);
  143. /* Program conjugate parameter mixer resources */
  144. if (MEMWR == src->mode)
  145. return 0;
  146. for (i = 1; i < src->rsc.msr; i++) {
  147. src->rsc.ops->next_conj(&src->rsc);
  148. hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
  149. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  150. src->rsc.ctrl_blk);
  151. }
  152. src->rsc.ops->master(&src->rsc);
  153. return 0;
  154. }
  155. static int src_get_ca(struct src *src)
  156. {
  157. struct hw *hw;
  158. hw = src->rsc.hw;
  159. return hw->src_get_ca(hw, src->rsc.ops->index(&src->rsc),
  160. src->rsc.ctrl_blk);
  161. }
  162. static int src_init(struct src *src)
  163. {
  164. src_default_config[src->mode](src);
  165. return 0;
  166. }
  167. static struct src *src_next_interleave(struct src *src)
  168. {
  169. return src->intlv;
  170. }
  171. static int src_default_config_memrd(struct src *src)
  172. {
  173. struct hw *hw = src->rsc.hw;
  174. unsigned int rsr, msr;
  175. hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
  176. hw->src_set_bm(src->rsc.ctrl_blk, 1);
  177. for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
  178. rsr++;
  179. hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
  180. hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
  181. hw->src_set_wr(src->rsc.ctrl_blk, 0);
  182. hw->src_set_pm(src->rsc.ctrl_blk, 0);
  183. hw->src_set_rom(src->rsc.ctrl_blk, 0);
  184. hw->src_set_vo(src->rsc.ctrl_blk, 0);
  185. hw->src_set_st(src->rsc.ctrl_blk, 0);
  186. hw->src_set_ilsz(src->rsc.ctrl_blk, src->multi - 1);
  187. hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
  188. hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
  189. hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
  190. hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
  191. hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
  192. hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
  193. src->rsc.ops->master(&src->rsc);
  194. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  195. src->rsc.ctrl_blk);
  196. for (msr = 1; msr < src->rsc.msr; msr++) {
  197. src->rsc.ops->next_conj(&src->rsc);
  198. hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
  199. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  200. src->rsc.ctrl_blk);
  201. }
  202. src->rsc.ops->master(&src->rsc);
  203. return 0;
  204. }
  205. static int src_default_config_memwr(struct src *src)
  206. {
  207. struct hw *hw = src->rsc.hw;
  208. hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
  209. hw->src_set_bm(src->rsc.ctrl_blk, 1);
  210. hw->src_set_rsr(src->rsc.ctrl_blk, 0);
  211. hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
  212. hw->src_set_wr(src->rsc.ctrl_blk, 1);
  213. hw->src_set_pm(src->rsc.ctrl_blk, 0);
  214. hw->src_set_rom(src->rsc.ctrl_blk, 0);
  215. hw->src_set_vo(src->rsc.ctrl_blk, 0);
  216. hw->src_set_st(src->rsc.ctrl_blk, 0);
  217. hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
  218. hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
  219. hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
  220. hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
  221. hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
  222. hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
  223. hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
  224. src->rsc.ops->master(&src->rsc);
  225. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  226. src->rsc.ctrl_blk);
  227. return 0;
  228. }
  229. static int src_default_config_arcrw(struct src *src)
  230. {
  231. struct hw *hw = src->rsc.hw;
  232. unsigned int rsr, msr;
  233. unsigned int dirty;
  234. hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
  235. hw->src_set_bm(src->rsc.ctrl_blk, 0);
  236. for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
  237. rsr++;
  238. hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
  239. hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_F32);
  240. hw->src_set_wr(src->rsc.ctrl_blk, 0);
  241. hw->src_set_pm(src->rsc.ctrl_blk, 0);
  242. hw->src_set_rom(src->rsc.ctrl_blk, 0);
  243. hw->src_set_vo(src->rsc.ctrl_blk, 0);
  244. hw->src_set_st(src->rsc.ctrl_blk, 0);
  245. hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
  246. hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
  247. hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
  248. /*hw->src_set_sa(src->rsc.ctrl_blk, 0x100);*/
  249. hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
  250. /*hw->src_set_la(src->rsc.ctrl_blk, 0x03ffffe0);*/
  251. hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
  252. hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
  253. hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
  254. dirty = hw->src_get_dirty(src->rsc.ctrl_blk);
  255. src->rsc.ops->master(&src->rsc);
  256. for (msr = 0; msr < src->rsc.msr; msr++) {
  257. hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
  258. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  259. src->rsc.ctrl_blk);
  260. src->rsc.ops->next_conj(&src->rsc);
  261. }
  262. src->rsc.ops->master(&src->rsc);
  263. return 0;
  264. }
  265. static const struct src_rsc_ops src_rsc_ops = {
  266. .set_state = src_set_state,
  267. .set_bm = src_set_bm,
  268. .set_sf = src_set_sf,
  269. .set_pm = src_set_pm,
  270. .set_rom = src_set_rom,
  271. .set_vo = src_set_vo,
  272. .set_st = src_set_st,
  273. .set_bp = src_set_bp,
  274. .set_cisz = src_set_cisz,
  275. .set_ca = src_set_ca,
  276. .set_sa = src_set_sa,
  277. .set_la = src_set_la,
  278. .set_pitch = src_set_pitch,
  279. .set_clr_zbufs = src_set_clear_zbufs,
  280. .commit_write = src_commit_write,
  281. .get_ca = src_get_ca,
  282. .init = src_init,
  283. .next_interleave = src_next_interleave,
  284. };
  285. static int
  286. src_rsc_init(struct src *src, u32 idx,
  287. const struct src_desc *desc, struct src_mgr *mgr)
  288. {
  289. int err;
  290. int i, n;
  291. struct src *p;
  292. n = (MEMRD == desc->mode) ? desc->multi : 1;
  293. for (i = 0, p = src; i < n; i++, p++) {
  294. err = rsc_init(&p->rsc, idx + i, SRC, desc->msr, mgr->mgr.hw);
  295. if (err)
  296. goto error1;
  297. /* Initialize src specific rsc operations */
  298. p->ops = &src_rsc_ops;
  299. p->multi = (0 == i) ? desc->multi : 1;
  300. p->mode = desc->mode;
  301. src_default_config[desc->mode](p);
  302. mgr->src_enable(mgr, p);
  303. p->intlv = p + 1;
  304. }
  305. (--p)->intlv = NULL; /* Set @intlv of the last SRC to NULL */
  306. mgr->commit_write(mgr);
  307. return 0;
  308. error1:
  309. for (i--, p--; i >= 0; i--, p--) {
  310. mgr->src_disable(mgr, p);
  311. rsc_uninit(&p->rsc);
  312. }
  313. mgr->commit_write(mgr);
  314. return err;
  315. }
  316. static int src_rsc_uninit(struct src *src, struct src_mgr *mgr)
  317. {
  318. int i, n;
  319. struct src *p;
  320. n = (MEMRD == src->mode) ? src->multi : 1;
  321. for (i = 0, p = src; i < n; i++, p++) {
  322. mgr->src_disable(mgr, p);
  323. rsc_uninit(&p->rsc);
  324. p->multi = 0;
  325. p->ops = NULL;
  326. p->mode = NUM_SRCMODES;
  327. p->intlv = NULL;
  328. }
  329. mgr->commit_write(mgr);
  330. return 0;
  331. }
  332. static int
  333. get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc)
  334. {
  335. unsigned int idx = SRC_RESOURCE_NUM;
  336. int err;
  337. struct src *src;
  338. unsigned long flags;
  339. *rsrc = NULL;
  340. /* Check whether there are sufficient src resources to meet request. */
  341. spin_lock_irqsave(&mgr->mgr_lock, flags);
  342. if (MEMRD == desc->mode)
  343. err = mgr_get_resource(&mgr->mgr, desc->multi, &idx);
  344. else
  345. err = mgr_get_resource(&mgr->mgr, 1, &idx);
  346. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  347. if (err) {
  348. dev_err(mgr->card->dev,
  349. "Can't meet SRC resource request!\n");
  350. return err;
  351. }
  352. /* Allocate mem for master src resource */
  353. if (MEMRD == desc->mode)
  354. src = kcalloc(desc->multi, sizeof(*src), GFP_KERNEL);
  355. else
  356. src = kzalloc(sizeof(*src), GFP_KERNEL);
  357. if (!src) {
  358. err = -ENOMEM;
  359. goto error1;
  360. }
  361. err = src_rsc_init(src, idx, desc, mgr);
  362. if (err)
  363. goto error2;
  364. *rsrc = src;
  365. return 0;
  366. error2:
  367. kfree(src);
  368. error1:
  369. spin_lock_irqsave(&mgr->mgr_lock, flags);
  370. if (MEMRD == desc->mode)
  371. mgr_put_resource(&mgr->mgr, desc->multi, idx);
  372. else
  373. mgr_put_resource(&mgr->mgr, 1, idx);
  374. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  375. return err;
  376. }
  377. static int put_src_rsc(struct src_mgr *mgr, struct src *src)
  378. {
  379. unsigned long flags;
  380. spin_lock_irqsave(&mgr->mgr_lock, flags);
  381. src->rsc.ops->master(&src->rsc);
  382. if (MEMRD == src->mode)
  383. mgr_put_resource(&mgr->mgr, src->multi,
  384. src->rsc.ops->index(&src->rsc));
  385. else
  386. mgr_put_resource(&mgr->mgr, 1, src->rsc.ops->index(&src->rsc));
  387. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  388. src_rsc_uninit(src, mgr);
  389. kfree(src);
  390. return 0;
  391. }
  392. static int src_enable_s(struct src_mgr *mgr, struct src *src)
  393. {
  394. struct hw *hw = mgr->mgr.hw;
  395. int i;
  396. src->rsc.ops->master(&src->rsc);
  397. for (i = 0; i < src->rsc.msr; i++) {
  398. hw->src_mgr_enbs_src(mgr->mgr.ctrl_blk,
  399. src->rsc.ops->index(&src->rsc));
  400. src->rsc.ops->next_conj(&src->rsc);
  401. }
  402. src->rsc.ops->master(&src->rsc);
  403. return 0;
  404. }
  405. static int src_enable(struct src_mgr *mgr, struct src *src)
  406. {
  407. struct hw *hw = mgr->mgr.hw;
  408. int i;
  409. src->rsc.ops->master(&src->rsc);
  410. for (i = 0; i < src->rsc.msr; i++) {
  411. hw->src_mgr_enb_src(mgr->mgr.ctrl_blk,
  412. src->rsc.ops->index(&src->rsc));
  413. src->rsc.ops->next_conj(&src->rsc);
  414. }
  415. src->rsc.ops->master(&src->rsc);
  416. return 0;
  417. }
  418. static int src_disable(struct src_mgr *mgr, struct src *src)
  419. {
  420. struct hw *hw = mgr->mgr.hw;
  421. int i;
  422. src->rsc.ops->master(&src->rsc);
  423. for (i = 0; i < src->rsc.msr; i++) {
  424. hw->src_mgr_dsb_src(mgr->mgr.ctrl_blk,
  425. src->rsc.ops->index(&src->rsc));
  426. src->rsc.ops->next_conj(&src->rsc);
  427. }
  428. src->rsc.ops->master(&src->rsc);
  429. return 0;
  430. }
  431. static int src_mgr_commit_write(struct src_mgr *mgr)
  432. {
  433. struct hw *hw = mgr->mgr.hw;
  434. hw->src_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
  435. return 0;
  436. }
  437. int src_mgr_create(struct hw *hw, struct src_mgr **rsrc_mgr)
  438. {
  439. int err, i;
  440. struct src_mgr *src_mgr;
  441. *rsrc_mgr = NULL;
  442. src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL);
  443. if (!src_mgr)
  444. return -ENOMEM;
  445. err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw);
  446. if (err)
  447. goto error1;
  448. spin_lock_init(&src_mgr->mgr_lock);
  449. conj_mask = hw->src_dirty_conj_mask();
  450. src_mgr->get_src = get_src_rsc;
  451. src_mgr->put_src = put_src_rsc;
  452. src_mgr->src_enable_s = src_enable_s;
  453. src_mgr->src_enable = src_enable;
  454. src_mgr->src_disable = src_disable;
  455. src_mgr->commit_write = src_mgr_commit_write;
  456. src_mgr->card = hw->card;
  457. /* Disable all SRC resources. */
  458. for (i = 0; i < 256; i++)
  459. hw->src_mgr_dsb_src(src_mgr->mgr.ctrl_blk, i);
  460. hw->src_mgr_commit_write(hw, src_mgr->mgr.ctrl_blk);
  461. *rsrc_mgr = src_mgr;
  462. return 0;
  463. error1:
  464. kfree(src_mgr);
  465. return err;
  466. }
  467. int src_mgr_destroy(struct src_mgr *src_mgr)
  468. {
  469. rsc_mgr_uninit(&src_mgr->mgr);
  470. kfree(src_mgr);
  471. return 0;
  472. }
  473. /* SRCIMP resource manager operations */
  474. static int srcimp_master(struct rsc *rsc)
  475. {
  476. rsc->conj = 0;
  477. return rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0];
  478. }
  479. static int srcimp_next_conj(struct rsc *rsc)
  480. {
  481. rsc->conj++;
  482. return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
  483. }
  484. static int srcimp_index(const struct rsc *rsc)
  485. {
  486. return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
  487. }
  488. static const struct rsc_ops srcimp_basic_rsc_ops = {
  489. .master = srcimp_master,
  490. .next_conj = srcimp_next_conj,
  491. .index = srcimp_index,
  492. .output_slot = NULL,
  493. };
  494. static int srcimp_map(struct srcimp *srcimp, struct src *src, struct rsc *input)
  495. {
  496. struct imapper *entry;
  497. int i;
  498. srcimp->rsc.ops->master(&srcimp->rsc);
  499. src->rsc.ops->master(&src->rsc);
  500. input->ops->master(input);
  501. /* Program master and conjugate resources */
  502. for (i = 0; i < srcimp->rsc.msr; i++) {
  503. entry = &srcimp->imappers[i];
  504. entry->slot = input->ops->output_slot(input);
  505. entry->user = src->rsc.ops->index(&src->rsc);
  506. entry->addr = srcimp->rsc.ops->index(&srcimp->rsc);
  507. srcimp->mgr->imap_add(srcimp->mgr, entry);
  508. srcimp->mapped |= (0x1 << i);
  509. srcimp->rsc.ops->next_conj(&srcimp->rsc);
  510. input->ops->next_conj(input);
  511. }
  512. srcimp->rsc.ops->master(&srcimp->rsc);
  513. input->ops->master(input);
  514. return 0;
  515. }
  516. static int srcimp_unmap(struct srcimp *srcimp)
  517. {
  518. int i;
  519. /* Program master and conjugate resources */
  520. for (i = 0; i < srcimp->rsc.msr; i++) {
  521. if (srcimp->mapped & (0x1 << i)) {
  522. srcimp->mgr->imap_delete(srcimp->mgr,
  523. &srcimp->imappers[i]);
  524. srcimp->mapped &= ~(0x1 << i);
  525. }
  526. }
  527. return 0;
  528. }
  529. static const struct srcimp_rsc_ops srcimp_ops = {
  530. .map = srcimp_map,
  531. .unmap = srcimp_unmap
  532. };
  533. static int srcimp_rsc_init(struct srcimp *srcimp,
  534. const struct srcimp_desc *desc,
  535. struct srcimp_mgr *mgr)
  536. {
  537. int err;
  538. err = rsc_init(&srcimp->rsc, srcimp->idx[0],
  539. SRCIMP, desc->msr, mgr->mgr.hw);
  540. if (err)
  541. return err;
  542. /* Reserve memory for imapper nodes */
  543. srcimp->imappers = kzalloc(sizeof(struct imapper)*desc->msr,
  544. GFP_KERNEL);
  545. if (!srcimp->imappers) {
  546. err = -ENOMEM;
  547. goto error1;
  548. }
  549. /* Set srcimp specific operations */
  550. srcimp->rsc.ops = &srcimp_basic_rsc_ops;
  551. srcimp->ops = &srcimp_ops;
  552. srcimp->mgr = mgr;
  553. srcimp->rsc.ops->master(&srcimp->rsc);
  554. return 0;
  555. error1:
  556. rsc_uninit(&srcimp->rsc);
  557. return err;
  558. }
  559. static int srcimp_rsc_uninit(struct srcimp *srcimp)
  560. {
  561. if (NULL != srcimp->imappers) {
  562. kfree(srcimp->imappers);
  563. srcimp->imappers = NULL;
  564. }
  565. srcimp->ops = NULL;
  566. srcimp->mgr = NULL;
  567. rsc_uninit(&srcimp->rsc);
  568. return 0;
  569. }
  570. static int get_srcimp_rsc(struct srcimp_mgr *mgr,
  571. const struct srcimp_desc *desc,
  572. struct srcimp **rsrcimp)
  573. {
  574. int err, i;
  575. unsigned int idx;
  576. struct srcimp *srcimp;
  577. unsigned long flags;
  578. *rsrcimp = NULL;
  579. /* Allocate mem for SRCIMP resource */
  580. srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL);
  581. if (!srcimp)
  582. return -ENOMEM;
  583. /* Check whether there are sufficient SRCIMP resources. */
  584. err = 0;
  585. spin_lock_irqsave(&mgr->mgr_lock, flags);
  586. for (i = 0; i < desc->msr; i++) {
  587. err = mgr_get_resource(&mgr->mgr, 1, &idx);
  588. if (err)
  589. break;
  590. srcimp->idx[i] = idx;
  591. }
  592. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  593. if (err) {
  594. dev_err(mgr->card->dev,
  595. "Can't meet SRCIMP resource request!\n");
  596. goto error1;
  597. }
  598. err = srcimp_rsc_init(srcimp, desc, mgr);
  599. if (err)
  600. goto error1;
  601. *rsrcimp = srcimp;
  602. return 0;
  603. error1:
  604. spin_lock_irqsave(&mgr->mgr_lock, flags);
  605. for (i--; i >= 0; i--)
  606. mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
  607. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  608. kfree(srcimp);
  609. return err;
  610. }
  611. static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp)
  612. {
  613. unsigned long flags;
  614. int i;
  615. spin_lock_irqsave(&mgr->mgr_lock, flags);
  616. for (i = 0; i < srcimp->rsc.msr; i++)
  617. mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
  618. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  619. srcimp_rsc_uninit(srcimp);
  620. kfree(srcimp);
  621. return 0;
  622. }
  623. static int srcimp_map_op(void *data, struct imapper *entry)
  624. {
  625. struct rsc_mgr *mgr = &((struct srcimp_mgr *)data)->mgr;
  626. struct hw *hw = mgr->hw;
  627. hw->srcimp_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
  628. hw->srcimp_mgr_set_imapuser(mgr->ctrl_blk, entry->user);
  629. hw->srcimp_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
  630. hw->srcimp_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
  631. hw->srcimp_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
  632. return 0;
  633. }
  634. static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry)
  635. {
  636. unsigned long flags;
  637. int err;
  638. spin_lock_irqsave(&mgr->imap_lock, flags);
  639. if ((0 == entry->addr) && (mgr->init_imap_added)) {
  640. input_mapper_delete(&mgr->imappers,
  641. mgr->init_imap, srcimp_map_op, mgr);
  642. mgr->init_imap_added = 0;
  643. }
  644. err = input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr);
  645. spin_unlock_irqrestore(&mgr->imap_lock, flags);
  646. return err;
  647. }
  648. static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry)
  649. {
  650. unsigned long flags;
  651. int err;
  652. spin_lock_irqsave(&mgr->imap_lock, flags);
  653. err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr);
  654. if (list_empty(&mgr->imappers)) {
  655. input_mapper_add(&mgr->imappers, mgr->init_imap,
  656. srcimp_map_op, mgr);
  657. mgr->init_imap_added = 1;
  658. }
  659. spin_unlock_irqrestore(&mgr->imap_lock, flags);
  660. return err;
  661. }
  662. int srcimp_mgr_create(struct hw *hw, struct srcimp_mgr **rsrcimp_mgr)
  663. {
  664. int err;
  665. struct srcimp_mgr *srcimp_mgr;
  666. struct imapper *entry;
  667. *rsrcimp_mgr = NULL;
  668. srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL);
  669. if (!srcimp_mgr)
  670. return -ENOMEM;
  671. err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw);
  672. if (err)
  673. goto error1;
  674. spin_lock_init(&srcimp_mgr->mgr_lock);
  675. spin_lock_init(&srcimp_mgr->imap_lock);
  676. INIT_LIST_HEAD(&srcimp_mgr->imappers);
  677. entry = kzalloc(sizeof(*entry), GFP_KERNEL);
  678. if (!entry) {
  679. err = -ENOMEM;
  680. goto error2;
  681. }
  682. entry->slot = entry->addr = entry->next = entry->user = 0;
  683. list_add(&entry->list, &srcimp_mgr->imappers);
  684. srcimp_mgr->init_imap = entry;
  685. srcimp_mgr->init_imap_added = 1;
  686. srcimp_mgr->get_srcimp = get_srcimp_rsc;
  687. srcimp_mgr->put_srcimp = put_srcimp_rsc;
  688. srcimp_mgr->imap_add = srcimp_imap_add;
  689. srcimp_mgr->imap_delete = srcimp_imap_delete;
  690. srcimp_mgr->card = hw->card;
  691. *rsrcimp_mgr = srcimp_mgr;
  692. return 0;
  693. error2:
  694. rsc_mgr_uninit(&srcimp_mgr->mgr);
  695. error1:
  696. kfree(srcimp_mgr);
  697. return err;
  698. }
  699. int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr)
  700. {
  701. unsigned long flags;
  702. /* free src input mapper list */
  703. spin_lock_irqsave(&srcimp_mgr->imap_lock, flags);
  704. free_input_mapper_list(&srcimp_mgr->imappers);
  705. spin_unlock_irqrestore(&srcimp_mgr->imap_lock, flags);
  706. rsc_mgr_uninit(&srcimp_mgr->mgr);
  707. kfree(srcimp_mgr);
  708. return 0;
  709. }